state
向class组件中添加局部的state
官方代码如下:
class Clock extends React.Component {
constructor(props) {
//这部分是es6的知识,不了解的小伙伴可以去看一下es6入门或者冴羽老师的博客
//这里官方有句概括性很强的话:
//Class 组件应该始终使用 props 参数来调用父类的构造函数
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
setState
首先需要明确的是setState的异步并不是内部代码的异步,setState本身和代码的执行过程同步,只是在部分事件和情况下因为调用事件本身执行顺序和event loop的原因导致的一些问题,要想避免在无论什么时候都可以实时得到state中的值最好的办法就是获取使用它的第二个参数回调函数。
合成事件(异步)
在React中的onClick、onBlur、onChange这类事件都是合成事件,在这类事件中有一个try...finally...
的模块,就是先执行try中的模块然后执行finally中的模块,在try中首先会进行获取到你的值,但是并不会更新,在finally中更新state并且渲染UI。
生命周期函数(异步)
和合成事件是差不多的,但是在生命周期执行过程中并不会进行更新,而是执行结束后才开始去做数据的更新。
原生事件(同步)
当你使用原生事件时避开了jsx提供的那一套合成函数的封装和内部逻辑,所以就使得你可以同步拿到更新后的值。
setTimeout(同步)
基于Event Loop提供的好处,当你在setTimeout中使用setState时,首先会将setTimeout放到队列中,然后去执行其中finally
的部分,也就是跳过了内部的第一层判断从而避开了对setState进行异步处理的操作。
setState(批量覆盖)
state = {count: 0}
setState({count: this.state.count + 1})
setState({count: this.state.count + 1})
setState({count: this.state.count + 1})
setState({count: this.state.count + 1})
在上面的代码中,最终结果只是1,因为在批量操作中setState会对重复相同操作覆盖,如果时多个不相同的操作则就官方文档中的合并。
生命周期(先搞懂为啥)
直接上大图
官方的流程(这里我们只看生命周期图中的生命周期)
constructor()
(初始化)- 进行state初始化和函数的this的绑定
- 注意:任何复杂的操作包括setState都不应该出现在该函数中
static getDerivedStateFromProps(props, state)
(state 的值在任何时候都取决于 props时使用)- 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
- 该函数应返回一个对象来更新 state,如果返回 null 则不更新任何内容。
- 此方法无权访问组件实例。
- 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
shouldComponentUpdate(nextProps, nextState)
(用于控制state的改变是否应该进行重新渲染)- 渲染之前被执行通过返回值的true或false来判断是否进行重新渲染。
- 请勿在此进行任何复杂的比较和操作,因为这会造成严重的性能损伤。
render
(返回应当渲染的元素的纯函数)- 当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回以下类型之一
- 由JSX创建的React元素
- 数组或 fragments。
- 当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回以下类型之一
componentDidMount()
在组件挂载也就是插入DOM树后调用- 在这里比较适合添加一些复杂功能,比如发布订阅和ajax请求,但是相对的,在这里进行state的初始化时会触发额外的渲染。
getSnapshotBeforeUpdate()
(获取快照)- 需要注意的是该函数并不会在挂载时执行,而只是在最近一次渲染输出(提交到 DOM 节点)之前调用(也就是render将元素转为React元素后到在页面上呈现出来的过程之间调用),这是属于更新时调用的函数。
componentDidUpdate(prevProps, prevState, snapshot)
(更新后立刻被调用)- 首次渲染不执行更新后会被立即调用。
你也可以在 componentDidUpdate() 中直接调用 setState(),但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。不要将 props “镜像”给 state,请考虑直接使用 props。 --React官方文档
- 这里导致的死循环和props赋值带来的组件性能的影响往往是致命的,可能你没遇到这样的情况,但当你使用过hook之后你想进行ajax数据请求的时候就有很大可能出现这一问题。
componentWillUnmount()
组件卸载和销毁时- 这里往往需要做一些收尾工作,比如清除timer和取消网络请求
- 切记:在这里不要调用setState()
梳理一下我们可以理解的生命周期流程
上面的内容可能看的你有些烦躁,但是如果你对上面的内容有所了解后,接下里便轻松多了:
看到这里,对于生命周期,你是否有所了解了呢?
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!