开始学习React啦(三)_Reac

一、组件生命周期

所谓的生命周期就是指某个事物从开始到结束的各个阶段,当然在 React 中指的是组件从创建到销毁的过程

在这个过程中的不同阶段调用的函数,即生命周期本质就是一个函数,到了特定时机会自动执行

通过这些函数,我们可以更加精确的对组件进行控制

下面通过一张生命周期流程图进行一个分析

开始学习React啦(三)_Reac_02

我们可以将生命周期分成两个阶段:

  • 挂载阶段
  • 更新阶段
  • 卸载阶段

挂载阶段

挂载阶段指的是组件创建的虚拟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} />复制代码