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的单向数据流的设计思想,在复用组件的时候,组件的数据也不会相互干扰,使代码逻辑上会更加便于管理。
React - 状态提升相关推荐
- react10_状态提升
react 状态提升 一个父组件和多个子组件时,本来应存在于子组件的state移动到父组件,子组件使用props,父组件的state作为子组件的props传入子组件,可以使用子组件的功能,使子组件数据 ...
- [react] react的状态提升是什么?使用场景有哪些
[react] react的状态提升是什么?使用场景有哪些 React的状态提升就是用户对子组件操作,子组件不改变自己的状态,通过自己的props把这个操作改变的数据传递给父组件,改变父组件的状态,从 ...
- React 第十章 状态提升
1,什么是状态提升? 在很多情况下我们在React组件中 数据并不一定只是在组件内部使用,我们有可能需要将组件中的数据共享出来,在其他组件中使用.但之前我们说过React是一个单向数据流,只能将数据通 ...
- React学习笔记(五) 状态提升
状态提升究竟是什么东西呢?别急,下面让我们一步一步来看看究竟要怎么使用状态提升 假设我们有这样一个需求,提供两个输入框(分别属于两个组件),保证输入框里面的内容同步 好,下面我们先来封装一个输入框组件 ...
- web前端高级React - React从入门到进阶之组件的状态提升
系列文章目录 第一章:React从入门到进阶之初识React 第一章:React从入门到进阶之JSX简介 第三章:React从入门到进阶之元素渲染 第四章:React从入门到进阶之JSX虚拟DOM渲染 ...
- 状态提升(精读React官方文档—10)
为什么需要状态提升? 有时候,多个组件需要共享状态,此时需要将共享状态提升到最近的共同父组件中去. 首先创建一个判断水是否沸腾的组件BoilingVerdict celsius 温度作为一个 prop ...
- react进入路由前获取数据_react之传递数据的几种方式props传值、路由传值、状态提升、redux、context...
父组件: import { Route, Switch, Redirect } from 'react-router-dom' class App extends Component { render ...
- uiswitchbutton 点击不改变状态_Redux 包教包会(一):解救 React 状态危机
前端应用的状态管理日益复杂.随着大前端时代的到来,前端愈来愈注重处理逻辑,而不只是专注 UI 层面的改进,而以 React 为代表的前端框架的出现,大大简化了我们编写 UI 界面的复杂度.虽然 Rea ...
- [译] ⚛ React 状态管理工具博物馆
原文地址:⚛ The React State Museum: ⚡️View the hottest state management libs for React 原文作者:Gant Laborde ...
最新文章
- 修改git的远程仓库命令
- 同步机制之 ReentrantLock
- Android自定义流式布局-FlowLayout
- java switch 应用
- php jquery点击事件,jQuery操作html元素点击事件详解
- BeyondCompare4如何破解
- 算法精讲:分享一道值得分享的算法题
- C和指针之字符串之实现strcpy函数
- expected function body after function declarator
- 在ASP.NET中防止注入攻击[翻译]
- 【英语学习】【WOTD】inexorable 释义/词源/示例
- [style] visibility
- Caffe傻瓜系列(2):视觉层(Vision Layers)及参数
- java web服务器cpu占用过高的处理 (2014-07-21 17:17:36)
- WiFi 2.4G/5G/6G信道分布
- VelocityTracker 使用
- Android5.0新特性:RecyclerView实现上拉加载更多
- 办公邮箱哪个比较好,企业电子邮箱官网在哪里?
- Markdown 前言
- 【转载】爸妈,求你们不要这么懂事
热门文章
- ascii modbus vc源码_MODBUS ASCII及MODBUS RTU通讯
- Redis 中常用命令
- python进阶(第三章1) 字典
- 软件设计师中级 百度知道_设计师应该知道什么
- Git 和 GitHub 教程——版本控制入门
- 学习underscore源码整体架构,打造属于自己的函数式编程类库
- HDU 1253 胜利大逃亡 题解
- 软考新思维--2017年上半年信息系统项目管理师上午试题分析与答案(试题6-10题)...
- 关于Android studio找不到sqlite数据库的解决方法
- 微信公众平台消息接口开发(2)-封装weixin.class.php