美文网首页
React 生命周期及相关用法

React 生命周期及相关用法

作者: 行走的蛋白质 | 来源:发表于2019-12-31 16:13 被阅读0次
    • 创建阶段
      componentWillMount():实例挂载之前
      render()
      componentDidMount():实例挂载完成。一般在这个函数中与后台进行初始化数据交互

    • 运行更新阶段
      componentWillReceiveProps(nextProps):父组件改变时调用。
      shouldComponentUpdate(nextProps, nextState):主要是用来手动阻止组件渲染,一般在这个函数中做组件的性能优化。
      componentWillUpdate(nextProps, nextState):组件数据更新前调用
      render()
      componentDidUpdate(prevProps, prevState):组件数据更新完成时调用
      render(): 渲染组件

    • 卸载阶段
      componentWillUnmount():销毁阶段。一般用来销毁不用的变量或者是解除无用定时器以及解绑无用事件。防止内存泄漏问题

    • react 新增生命周期
      getDerivedStateFromProps(nextProps, prevState)
      getSnapShotBeforeUpdate(prevProps, prevState)

    react 生命周期 react 生命周期
    阶段详解
    • constructor
      constructor 中完成了 react 数据的初始化,他接收两个参数: props 和 context,当想在函数内部使用这两个参数时,需要使用 super() 传入这两个参数
    constructor(props, context) {
        super(props, context)
    }
    

    注:只要使用了 constructor() 就必须写 super() 否则会导致 this 的指向错误。

    • componentWillMount()
      在服务渲染时使用,代表组件经历了 constructor() 初始化数据后,但是还未渲染 DOM 树

    • componentDidMount()
      组件第一次渲染完成,此时 DOM 节点已经生成,可以在这里调用 ajax 请求,返回数据 setState 后组件会重新渲染

    • componentWillReceiveProps (nextProps)
      1.在接受父组件改变后的 props 需要重新渲染得时候用到
      2.接受一个参数 nextProps
      3.通过对比 nextProps 和 this.props 将 nextProps 的 state 更新当前 state 从而重新渲染组件

    componentWillReceiveProps(nextPorps) {
        nextPorps.matchIndex !== this.state.matchIndex && this.setState({
            matchIndex: nextPorps.matchIndex
        }, () => {
            console.log(this.state.matchIndex:nextPorps)
        })
    }
    
    • shouldComponentUpdate(nextProps, nextState)
      1.主要用于性能优化 ( 部分更新 )
      2.唯一用于控制组件重新渲染的生命周期,由于在 react 中 setState 后 state 发生变化,组件会进入重新渲染的流程,在这里 return false 可以阻止组件的更新
      3.因为 react 父组件的重新渲染会导致其所有子组件的重新渲染,这个时候其实我们是不需要所有子组件都跟着重新渲染的,因此需要在子组件的该生命周期中做判断

    • componentWillUpdate (nextProps, nextState)
      shouldComponentUpdate 返回 true 后,组件进入重新渲染的流程,进入 componentWillUpdate,这里同样能拿到 nextProps 和 nextState

    • componentDidUpdate(prevProps, prevState)
      组件更新完毕后,react 只会在第一次初始化成功进入 componentDidMount,之后每次重新渲染都会进入这个生命周期,这里可以拿到 PrevProps 和 prevState,即更新前的 props 和 state

    • render()
      render 函数会插入 jsx 生成的 dom 结构,react 会生成一份虚拟 dom 树,在每一次组件更新时,react 会通过其 diff 算法比较更新前后新旧 DOM 树,比较以后找到最小的有差异的 DOM 节点,并重新渲染

    • componentWillUnmount ()
      在此处完成组件的卸载和数据的销毁
      1.clear 组件中的所有 setTimeout 和 setInterval
      2.移除所有组件中的监听removeEventListener
      3.有时候会碰到一个 warning:Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.
      原因是在组件中的 ajax 请求返回 setState,而组件销毁的时候,请求还未完成
      解决办法如下:

    componentDidMount() {
        this.isMount = true
        axios.post().then((res) => {
            this.isMount && this.setState({
                xxx: res
            })
        })
    }
    componentWillUnMount() {
        this.isMount = false
    }
    
    • getDerivedStateFromProps(nextProps, prevState)
      代替 componentWillReceiveProps()
      老版本中的 componentWillReceiveProps() 方法判断前后两个 props 是否相同,如果不同再将新的 props 更新到 state 上去,这样做来会破坏 state 数据的单一数据源,导致组件状态变得不可预测,另一方面也会增加组件的重绘次数。
    // before
    componentWillReceiveProps(nextProps) {
        if(nextProps.isLogin !== this.props.isLogin) {
            this.setState({
                isLogin: nextProps.isLogin
            })
        }
    
        if(nextProps.isLogin) {
            this.handleClose()
        }
    }
    
    // after
    static getDerivedStateFromProps(nextProps, prevState) {
        if(nextProps.isLogin !== prevState.isLogin) {
            return {
                isLogin: nextProps.isLogin
            }
        }
    
        return null
    }
    componentDidUpdate(prevProps, prevState) {
        if(!prevState.isLogin && this.props.isLogin) {
            this.handleClose()
        }
    }
    

    两者最大的不同:
    在 componentWillReceiveProps 中我们做两件事:
    1.根据 props 来更新 state
    2.触发一些回调,比如动画或者页面跳转等。
    而在新版本中:
    1.官方将更新 state 与触发回调重新分配到了 getDerivedStateFromProps 与 componentDidUpdate 中,使得组件整体的更新逻辑更加清晰。
    2.在 getDerivedStateFromProps 中还禁止了组件去访问 this.props,强制让开发者去比较 nextProps 和 prevState 中的值,以确保当前开发者用到 getDerivedStateFromProps 这个函数的时候就是根据当前的 props 来更新组件的 state,而不是去做一些其它让组件自身状态变的不可预测的事情。

    • getSnapshotBeforeUpdate(prevProps, prevState)
      代替 componentWillUpdate
      常见的 componentWillUpdate 是在组件更新前,读取当前某个 DOM 的状态,并在 componentDidUpdate 中进行相应的处理
      两者的区别:
      1.在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 状态并不总是和 commit 阶段相同,这就导致在 componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时候的值很有可能已经失效了
      2.getSnapShotBeforeUpdate 会在最终的 render 之前调用,也就是说在 getSnapShotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的,此生命周期返回的任何值都将作为参数传递给 componentDidUpdate()

    相关文章

      网友评论

          本文标题:React 生命周期及相关用法

          本文链接:https://www.haomeiwen.com/subject/jayjoctx.html