React - 状态提升

从入门的角度来聊一下React 的状态提升。

我们先来看一下React官网是怎么介绍这一概念的:

使用 react 经常会遇到几个组件需要共用状态数据的情况。这种情况下,我们最好将这部分共享的状态提升至他们最近的父组件当中进行管理。

很简单的一句介绍,由此我们可以很清楚的明白React状态提升主要就是用来处理父组件和子组件的数据传递的;他可以让我们的数据流动的形式是自顶向下单向流动的,所有组件的数据都是来自于他们的父辈组件,也都是由父辈组件来统一存储和修改,再传入子组件当中。

举个栗子

现在我们需要实现一个统计总价的功能:

1、首先,先写一个父组件:

class Category extends React.Component { constructor(props){super(props);this.state = {name: "React.JS"}}render(){return <h1>{this.state.name}</h1>}
}
ReactDOM.render(<Category />,document.getElementById('app')
)复制代码
2、再定义一个子组件,并拿到父组件传递下来的props值:

// 子组件
class Children extends React.Component {constructor(props){super(props);}render(){return(<div><label>{this.props.num}<input value={this.props.num} /><button>+</button></label></div>)}
}
// 父组件
class Category extends React.Component {constructor(props){super(props);this.state = {name: "React.JS",num1: 0}}render(){return(<div><h2>{this.state.num1}</h2><Children num={this.state.num1} /></div>)}
}复制代码

      现在我们可以看到,Children这个子组件的数据是从父组件传下来,通过this.props拿到          的,但是现在还不能在子组件上面去修改父组件的数据,所以我们的子组件的数据也无            法得到改变。

3、现在我们在子组件里面定义属性,来触发父组件的事件:

class Children extends React.Component {constructor(props){super(props);}// input输入框事件setNum(e){this.props.setNum(e.target.value)}// 按钮递增事件addNum(){this.props.addNum()}render(){return(<div><label>{this.props.num}<input onChange={(e)=>this.setNum(e)} value={this.props.num} /><button onClick={()=>this.addNum()}>+</button></label></div>)}
}
class Category extends React.Component {constructor(props){super(props);this.state = {name: "React.JS",// 将子组件的需要用到的数据存放在父组件内,在子组件内通过this.props可以取到num1: 0}}// 处理子组件传上来触发input输入框的处理事件setNum(e){this.setState({num1: parseInt(e)})}// 处理子组件传上来触发button按钮的处理事件addNum(){this.setState({num1: this.state.num1 += 1})}render(){return(<div><h2>{this.state.num1}</h2>// 子组件通过this.props可以触发对应绑定的事件来修改自身的数据<Children addNum={()=>this.addNum()} setNum={(e)=>this.setNum(e)} num={this.state.num1} /></div>)}
}复制代码

到这一步,功能已经实现了,子组件通过this.props去拿父组件的数据,并可以触发属性上面绑定的对应函数来修改父组件的数据,使子组件的数据得到更新;

其实可以看出,Children这个组件的数据不是独立的,而是来自Category组件传下来的,所以,这个Children组件是可以随意复用的,只需要在他的父组件Category上为他存放一个给她传递数据的变量就OK了。

1、首先,我们在Category类的构造函数里的this.state内添加一个新的变量来处理我们即将新       增的另一个子组件:

constructor(props){super(props);this.state = {name: "React.JS",num1: 0,// 添加一个用来处理新组件数据的变量num2: 0    <==================================================}
}复制代码

2、然后在Category组件里我们再写一个新的Children组件,属性上面绑定的数据全部换成们         刚才定义的新变量:

render(){return(<div><h2>{this.state.num1}</h2><Children addNum={()=>this.addNum()} setNum={(e)=>this.setNum(e)} num={this.state.num1} /><Children num={this.state.num2} /></div>)
}复制代码

3、给他绑定属性事件来修改处理他的变量:

class Category extends React.Component {constructor(props){super(props);this.state = {name: "React.JS",num1: 0,num2: 0}}
// 处理num1数据的子组件setNum(e){this.setState({num1: parseInt(e)})}addNum(){this.setState({num1: this.state.num1 += 1})}
// 处理num2数据的子组件newSetNum(e){this.setState({num2: parseInt(e)})}newAddNum(){this.setState({num2: this.state.num2 += 1})}render(){return(<div>// 这里接收两个组件的数据总和<h2>{this.state.num1 + this.state.num2}</h2><Children addNum={()=>this.addNum()} setNum={(e)=>this.setNum(e)} num={this.state.num1} />// 在属性上面绑定新的事件来处理该组件的事件<Children addNum={()=>this.newAddNum()} setNum={(e)=>this.newSetNum(e)} num={this.state.num2} /></div>)}
}复制代码

现在,看一下实际效果:


*总结:

所以,React的状态提升,其实是为了组件之间的数据更加单向性,在数据的传输上始终只会出现一对一的情况,在处理上,也方便我们只需要在向子组件传递数据的那个父辈组件上进行操作,并传回子组件,使得数据更新,这种方法也体现了React的单向数据流的设计思想,在复用组件的时候,组件的数据也不会相互干扰,使代码逻辑上会更加便于管理。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

saltstack(三) --- salt-httpapi

以下操作均在master上操作 1. 安装api netapi modules&#xff08;httpapi&#xff09;有三种&#xff0c;分别是rest_cherrypy、rest_tornado、rest_wsig&#xff0c;接下来要讲的是rest_cherrypydoc&#xff1a;https://docs.saltstack.com/en/latest/ref/netapi/all/salt.ne…

c++实现二叉搜索树

自己实现了一下二叉搜索树的数据结构。记录一下&#xff1a; #include <iostream>using namespace std;struct TreeNode{int val;TreeNode *left;TreeNode *right;TreeNode(int value) { valvalue; leftNULL; rightNULL; } };class SearchTree{public:SearchTree();~Sear…

一款自用的翻译小工具,开源了

一款自用的翻译小工具&#xff0c;开源了TranslationTool作者&#xff1a;WPFDevelopersOrg - 唐宋元明清|驚鏵原文链接&#xff1a;https://github.com/Kybs0/TranslationTool此项目使用WPF MVVM开发。框架使用大于等于.NET461。Visual Studio 2019。最初是支持以下&#xff1…

JS使用按位异或方式加密字符串

按位异或加密字符串&#xff0c;字符串加解密都是该函数 缺陷是加密密钥使用的字符最好不要出现需要加密的字符串中的字符&#xff0c;一旦出现原字符与加密字符一样额情况&#xff0c;异或结果为0&#xff0c;导致不能还原字符串&#xff0c;可以考虑更改算法避免这种情况 im…

SCSS 实用知识汇总

1、变量声明 $nav-color: #F90; nav {//$width 变量的作用域仅限于{}内$width: 100px;width: $width;color: $nav-color; }.a {//报错&#xff0c;$width未定义width: $width; } 2、父选择器& scss代码&#xff1a; article a {color: blue;&:hover { color: red } } 编…

【ELK集群+MQ】通用部署方案以及快速实现MQ发布订阅服务功能

前言&#xff1a;大概一年多前写过一个部署ELK系列的博客文章&#xff0c;前不久刚好在部署一个ELK的解决方案&#xff0c;我顺便就把一些基础的部分拎出来&#xff0c;再整合成一期文章。大概内容包括&#xff1a;搭建ELK集群&#xff0c;以及写一个简单的MQ服务。如果需要看一…

python容错

#try: except: else: #为什么叫容错呢&#xff0c;先说说错误&#xff0c;这里说的错误并不是因为马虎或者什么原因在脚本中留下的bug&#xff0c;这个不能容掉&#xff0c;所谓容掉就是略过这个错误&#xff0c;要在测试时候发现并修正&#xff0c;需要容错的错误是在脚本执行…

git stash参数介绍

git stash 用于暂存工作区未提交的内容&#xff0c;便于在同时开发多个分支需要切换时保存当前分支进度。 list 语法 git stash list [<options>] &#xff0c;与git log功能类似&#xff0c;列出储藏列表&#xff0c;options 参数可以参考git log的参数 show 语法 git …

多语言报表的改动方法

在定义上传RTF模板的时候&#xff0c;会有一个是否可翻译的选项&#xff0c;选择之后。就能够上传xlf文件作为翻译内容。 对于已经存在的多语言类型报表&#xff0c;稍作改动之后再上传&#xff0c;可能会出现下面现象&#xff1a; 进程出现了“未完毕”的提示 想要改动非常eas…

自定义Cell的流程

1、.h文件 // // 文 件 名:CHBackupGateWayCell.h // // 版权所有:Copyright © 2018 lelight. All rights reserved. // 创 建 者:lelight // 创建日期:2018/12/19. // 文档说明: // 修 改 人: // 修改日期: //#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGINclass…

JS实时监听DOM元素变化 - MutationObserver

使用 MutationObserver API实时监听DOM元素变化 创建 MutationObserver 实列&#xff0c;接受一个用于监听到DOM元素变化的回调函数 const handleListenChange (mutationsList, observer) > {console.log(mutationsList, observer) } const mutationObserver new Mutati…

LightOJ - 1027 A Dangerous Maze —— 期望

题目链接&#xff1a;https://vjudge.net/problem/LightOJ-1027 1027 - A Dangerous MazePDF (English)StatisticsForumTime Limit: 2 second(s)Memory Limit: 32 MBYou are in a maze; seeing n doors in front of you in beginning. You can choose any door you like. The p…

MASA MAUI Plugin (六)集成个推,实现本地消息推送[Android] 篇

背景MAUI的出现&#xff0c;赋予了广大.Net开发者开发多平台应用的能力&#xff0c;MAUI 是Xamarin.Forms演变而来&#xff0c;但是相比Xamarin性能更好&#xff0c;可扩展性更强&#xff0c;结构更简单。但是MAUI对于平台相关的实现并不完整。所以MASA团队开展了一个实验性项目…

第八天

配置文件 Vi /etc/fstab /dev/vg01/lv01 /dir01 ext4 defaults mount -a 扫描 使用交换空间 1.创建分区 2.mkswap /dev/sda创建交换分区 3.swapon /dev/sda启用交换分区 Linux系统启动过程 1、引导程序 BIOS自检 &#xff08;硬件自检&#xff09; 2、G…

iOS 通知中心(NSNotificationCenter)

NSNotificationCenter 在这里第一步和第二步的顺序可以互换&#xff0c;一般楼主我喜欢先在需要发送消息的页面发送消息&#xff0c;然后再在需要监听的页面注册监听。要注意的是不管是通知中心还是KVO都需要在页面销毁之前移除监听。 注册观察者/*** 观察者注册消息通知*…

vue-router和react-router嵌套路由layout配置方案的区别

最近在学习react&#xff0c;在路由这一块有点看不懂&#xff0c;第一感觉是灵活性很大&#xff0c;想怎么来就怎么来&#xff0c;但问题也来了&#xff0c;稍微复杂一点就GG了&#xff0c;不如vue的傻瓜式配置来的方便。 先说一下vue的路由配置方式&#xff0c;目录结构如下&…

微软加更.NET7中文手册,都有哪些新亮点?

11月8号发布了.NET7&#xff0c;从底层性能改进&#xff0c;到上层API升级&#xff0c;让.NET7综合性能再度提升&#xff01;同时发布了最新的C#11&#xff0c;也带来了很多小惊喜。如何快捷学习最新的.NET7和C#11&#xff1f;答案只有一个&#xff0c;微软官方中文文档&#x…

jquery对json的各种遍历

http://caibaojian.com/jquery-each-json.html转载于:https://www.cnblogs.com/pxffly/p/8442448.html

中级工程师之路

前言&#xff1a;之前在问答中问了一个问题 毕业半年感觉没什么进步该怎么办&#xff1f; 这个问题一直让我感觉比计较焦虑。于是在一个关于面试经验的博客中找到了一些灵感。就是通过问题进行学习&#xff0c;对自身的知识体系进行整理和补充。以问题作为切入点&#xff0c;不…

Vue在渲染函数createELement和JSX中使用插槽slot

Vue对于插槽有两个专门的APIvm.$slots和vm.$scopedSlots&#xff0c;分别是普通插槽和作用域插槽&#xff0c;使用JSX语法或渲染函数的时候&#xff0c;定义插槽将使用上述两个API。 渲染函数createElement 普通插槽和作用域插槽在定义上相差不大&#xff0c;但是在使用方法上…