React before16.3与after 16.3的生命周期详解以及简单应用场景

before React 16.3


父子组件样例:

//parent.jsx复制代码


//child.jsx
复制代码


React父子组件挂载阶段:

parent constructor
->parent componentWillMount
->parent render
->child constructor
->child componentWillMount
->child render
->child componentDidMount
->parent componentDidMount复制代码

React父子组件更新阶段:

parent shouldComponentUpdate
//shouldComponentUpdate的返回值 若是为true则向下执行 不然false将不会再向下执行
->parent componentWillUpdate
->parent render
->child componentWillReceiveProps
->child shouldComponentUpdate
->child componentWillUpdate
->child render
->child componentDidUpdate
->parent componentDidUpdate复制代码

React卸载阶段:

componentWillUnmount复制代码


constructor( props ):React的构造函数通常用来初始化state和为事件处理函数绑定实例,若是须要引入订阅或者反作用则请使用componentDidMount。

componentWillMount( ):它在render以前被调用,但不要在这里加入this.setState由于它并不会执行,并且不要在这个生命周期函数里去获取服务端数据,由于在render以前不会返回数据,因此它通常只用于服务端渲染。

componentWillReceiveProps( nextProps ): 通常用于子组件中使用,会在已挂载的父组件中接收新的props时被调用,能够用来比较this.props和nextProps的值去使用this.setState进行state变化。 须要注意的是,若是父组件致使子组件从新渲染,即便props没有改变,此函数也会被执行一次!在挂载过程当中,父组件初始化props不会致使子组件的此函数被调用,只有当父组件的props发生更新后调用此方法。

shouldComponentUpdate( nextProps, nextState ) : 当props或者state发生变化时,此函数会在渲染执行前被调用,默认返回值是true,可是使用该函数时必需要有一个Boolean返回值,不然浏览器会提示错误。此方法仅做为性能优化存在,比较this.props和nextProps还有this.state和nextState的值,返回false则React能够跳过这次更新,也不会再去调用componentWillUpdate、render、componentDidUpdate,可是此时子组件依然能够根据state的改变从新渲染。

componentWillUpdate( nextProps, nextState ) : 当组件的props或者state发生变化时,会在渲染执行以前被调用,但shouldComponentUpdate返回false时,今生命周期函数将不会被执行。在这里可使用this.setState,但须要进行his.props和nextProps还有this.state和nextState的值对比后再去改变state的值,不然将会形成死循环,浏览器内存占满后崩溃,建议在shouldComponentUpdate中去改变state的值。

render( ) : 当render被调用时,它会检查this.state和this.props的变化返回 React元素、数组或者Fragments、portals、字符串或者数值类型、boolean类型或者null。

componentDidMount( ) : 会在组件装载后当即被调用,可用来经过网络请求获取数据,直接使用this.setState更新state的值,也能够添加事件订阅,但须要在componentWillUnmount进行卸载订阅。

componentDidUpdate( preProps,preState ) : 会在更新后当即被调用,首次渲染不会执行此方法,但shouldComponentUpdate返回false时,今生命周期函数将不会被执行。 当组件更新完之后,对比更新先后props的值,若是不相等则能够去执行this.setState或者网络请求,可是没有条件比对直接去执行其余操做将会形成死循环。

componentWillUnmount( ) : 会在组件卸载或者销毁以前被调用。此函数用来必要的清除操做,好比clearInterval清除定时器,取消网络请求或者清除在componentDidMount中使用的订阅。这里不该该使用this.setState,由于组件永远不会从新渲染。

after React 16.3



static getDerivedStateFromProps( props, state ) : 会在render以前被调用,初次挂载或者更新后都会被调用,它应返回一个对象去更新state,返回null则不更新任何内容。这个生命周期函数也间接取代了老版本React中的componentWillReceiveProps、componentWillMount、componentWillUpdate这三个生命周期函数,但并非彻底取代,例如componentWillReceiveProps在只有父组件从新渲染时触发,但此函数在每次渲染以前都会被触发!它通常适用于让state的值一直被props所控制。

getSnapshotBeforeUpdate( preProps, preState ) : 会在最近一次渲染以前被调用到,使得它能够在组件更新以前从Dom中捕捉一些信息( 如滚动位置 ) , 此函数的任何返回值都将做为参数传递到componentDidUpdate的第三个参数里,此用法可用来UI处理滚动位置,不然尽可能不要去使用它!返回值是Snapshot值或者null。

componentDidUpdate( preProps, preState, snapshot ) : 用法同以前的React版本一致,但若是使用了getSnapshotBeforeUpdate( ),则它的返回值将做为componentDidUpdate的第三个返回值,不然此参数为unidentified。

Props直接给State传值的问题:

应用场景例如 每一个用户注册后都会有本身设置的密码,这时存储好的密码就是props,初始化为空的密码就是state,咱们须要去实现修改密码的功能,作法确定是将props直接传递给state,而后改变state的值再传输到服务端完成此功能。

这个功能实现过程当中,咱们不能直接将props赋值给state,只有监听props变化后才去改变state,但有时候会遇到特殊状况

componentWillReceiveProps(nextProps){
    if(nextProps.password !== this.props.password){
        this.setState({
            password: nextProps.password
                        })
        }
}复制代码
看上去上面的方法能解决问题,可是再想一想看,若是切换用户进行修改密码时,先后用户的密码如出一辙,则state不会进行改变,页面也不会从新渲染,也就至关于直接泄露密码了。

//before React 16.3
componentWillReceiveProps(nextProps){
    if(nextProps.userId !== this.props.userId){
        this.setState({
            password: nextProps.password
                      })
        }
}

//after React 16.3
state = {
    userId : this.props.userId,
    password : this.props.password
}
static getDerivedStateFromProps( props,state ){
    if( props.userId !== state.userId ){
           return{
                userId: props.userId
                password: props.password
            }
      }
        return null; 
}复制代码

这时判断state改变条件改为了监听用户的ID的变化,此时每次切换用户进行修改密码时都会使页面从新渲染,每次props的值都将从新赋值给state。

若有不对,麻烦请指出错误。数组

相关文章
相关标签/搜索