如何实现自己的react(4)生命周期

167 阅读2分钟

react的生命周期

React的生命周期,可以总结为初始化、加载、渲染、销毁四个阶段。我们先实现v16.4之前的生命周期,然后再想办法改写为最新的生命周期:

  1. componentWillMount(第一次render前调用一次)
  2. componentDidMount(第一次render后调用一次)
  3. render(渲染)
  4. componentWillReceiveProps(props变化就调用一次)
  5. componentWillUpdate(第一次render后每次render前)
  6. componentDidUpdate(第一次render后每次render后)
  7. componentWillunmount(销毁)

componentWillMount()和componentWillUpdate()

这是在第一次render前调用的生命周期,不建议在这里进行ajax请求,因为有可能在render前就返回结果后产生无效。 在mountComponent中,调用_tempDom.render()前,根据_tempDom有没有container判断是第一次渲染还是非第一次渲染:

if (vDom.isReactComponent) {
        const _tempDom = vDom;
        /**
         * 第一次render前调用componentWillMount()
         * 其余时候调用componentWillUpdate()
         */
        if (!_tempDom._container) {
            _tempDom.componentWillMount && _tempDom.componentWillMount();
        } else {
            _tempDom.componentWillUpdate && _tempDom.componentWillUpdate();
        }
        _tempDom._container = container;
        vDom = _tempDom.render();
    }

打印结果:

image.png

componenDidMount()和componentDidUpdate

同样是在mountComponent中,如果是第一次渲染完成就调用componentDidMount(),如果不是第一次渲染完成就在render后调用componentDidMount,由于渲染完后无论是不是第一次,_tempDom.container都会挂载到真实dom内,所以通过标识符来告诉引擎是不是第一次执行。

if (vDom.isReactComponent) {
        const _tempDom = vDom;
        /**
         * 第一次render前调用componentWillMount()
         * 其余时候调用componentWillUpdate()
         */
        let flag = false;
        if (!_tempDom._container) {
            _tempDom.componentWillMount && _tempDom.componentWillMount();
            flag = true;
        } else {
            _tempDom.componentWillUpdate && _tempDom.componentWillUpdate();
        }
        _tempDom._container = container;
        vDom = _tempDom.render();
        if (flag) {
            _tempDom.componentDidMount();
        } else {
            _tempDom.componentDidUpdate();
        }
    }

image.png

componentWillReceiveProps()和shouldComponentUpdate()

componentWillReceiveProps()是每次react组件接受到的props改变时,就会调用的生命周期方法,shouldComponentUpdate()返回的是一个布尔值,如果返回的是false,则就算props变化了,react组件也不会重新渲染。
但是如果想靠比较shouldComponentUpdate内的新旧props来优化是否要渲染,不太妥当,建议使用pureComponent和React.memo()
componentWillReceiveProps第一次render后不会调用,之后每次render时调用。
但是这里牵涉到了react关于如何更新父组件的state,以及判断节点是否变化之间的内容,所以打算放到之后的diff算法中一起讨论。
下一篇将去分析diff算法,最后形成一个能成功运行的简易生命周期~