一、组件生命周期
所谓的生命周期就是指某个事物从开始到结束的各个阶段,当然在 React 中指的是组件从创建到销毁的过程
在这个过程中的不同阶段调用的函数,即生命周期本质就是一个函数,到了特定时机会自动执行
通过这些函数,我们可以更加精确的对组件进行控制
下面通过一张生命周期流程图进行一个分析
我们可以将生命周期分成两个阶段:
- 挂载阶段
- 更新阶段
- 卸载阶段
挂载阶段
挂载阶段指的是组件创建的虚拟DOM,生成真实DOM,添加到我们指定的DOM节点中
涉及到生命周期有:
constructor
static getDerivedStateFromProps(props)
render
componentDidMount
constructor
即组件对象实例化阶段,常用于初始化数据(定义组件state与得到外部传入的props)
注意不能在里面使用this.setState
class App extentd App{constructor(props){this.setate = {} } }复制代码
也不要将props数据赋值给state
constructor(props) { super(props); // 不要这样做 this.state = { color: props.color }; }复制代码
如此做毫无必要(你可以直接使用 this.props.color),同时还产生了 bug(更新 prop 中的 color 时,并不会影响 state)
getDerivedStateFromProps(props)
从命名我们就得知,将传入的props映射到state上面
如果传入的内容不需要影响到组件的state,那么就需要返回一个null
class App extentd App{constructor(props){super(props)this.setate = {} }static getDerivedStateFromProps(nextProps, prevState) {const {type} = nextProps;// 当传入的type发生变化的时候,更新stateif (type !== prevState.type) {return { type, }; }// 否则,对于state不进行任何操作return null; } }复制代码
componentDidMount
组件挂载完成阶段,这时候页面真实DOM节点已经完成,我们可以进行一些副作用操作,如请求数据,或者获取真实DOM结构
componentDidMount(){this.loadData() // 异步加载数据}复制代码
render函数
render函数用于将VDOM生成真实DOM,是组件必须实现的方法
render(){return (<input type="text" defaultValue={inputValue} />) }复制代码
更新阶段
更新阶段主要为组件state数据发生变化,需要重新渲染,主要有如下:
- getDerivedStateFromProps
- shouldComponentUpdate
- render
- getSnapshotBeforeUpdate
- componentDidUpdate
这里主要讲述getSnapshotBeforeUpdate、componentDidUpdate这两个生命周期
getSnapshotBeforeUpdate
该生命周期代替componentWillUpdate
特点
读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的
返回的任何值都将作为参数传递给componentDidUpdate
getSnapshotBeforeUpdate(){return {foo:'foo'} }componentDidUpdate(prevProps, prevState,a){console.log(a) // {foo:'foo'}}复制代码
componentDidUpdate
可以拿到更新前的props和state,并且第三个参数能拿到getSnapshotBeforeUpdate返回的值
组件已经挂载完成,这时候state与DOM都是最新的
componentDidUpdate(prevProps, prevState,snapshot){console.log(snapshot) // {foo:'foo'}}复制代码
不要直接componentDidUpdate中调用this.setState,应该在判断语句if当中,否则会造成无限更新情况
componentDidUpdate(prevProps, prevState,snapshot){console.log(snapshot) // {foo:'foo'}}复制代码
二、受控组件与非受控组件
一句话讲,受控组件指的是将组件的内部状态与state保持一致
<input type"text" value={inputValue}/>复制代码
这时候在标签内输入值,我们会发现input标签的值并不会显示,原因是value值已经时刻被inputValue赋予了,inputValue值并没有发生变化
下面通过onChange事件修改inputValue值,从而实现控制组件的内部状态
<input type="text"value={inputValue} onChange={({ target }) => {this.setState({inputValue: target.value }) }} />复制代码
下面再来讲讲非受控组件,其无非也就是不与state产生关联
非受控组件如果想要设置初始值可以通过defaultValue、defaultChecked设置值
<input type="text" defaultValue={inputValue} />复制代码