前置知识:https://www.yuque.com/linhe-8mnf5/fxyxkm/sifrm7

1、老生命周期的使用

  1. // index.js
  2. import React from 'react';
  3. import ReactDOM from 'react-dom';
  4. class Counter extends React.Component {
  5. static defaultProps = { name: '计数器' }
  6. constructor(props) {
  7. super(props)
  8. this.state = { number: 0 }
  9. console.log('Counter 1.constructor初始化')
  10. }
  11. // eslint-disable-next-line react/no-deprecated
  12. componentWillMount() {
  13. console.log('Counter 2.conponentWillMount组件将要挂载')
  14. }
  15. componentDidMount() {
  16. console.log('Counter 4.conponentDidMount挂载完成')
  17. }
  18. handleClick = () => {
  19. this.setState({
  20. number: this.state.number + 1
  21. })
  22. }
  23. shouldComponentUpdate(nextProps, nextState) {
  24. console.log('Counter 5.shouldComponentUpdate询问组件是否需要更新?')
  25. return nextState.number % 2 === 0; // 偶true 基 false
  26. }
  27. //WARNING! To be deprecated in React v17. Use componentDidUpdate instead.
  28. // eslint-disable-next-line react/no-deprecated
  29. componentWillUpdate(nextProps, nextState) {
  30. console.log('Counter 6.componentWillUpdate组件将要更新')
  31. }
  32. componentDidUpdate(prevProps, prevState) {
  33. console.log('Counter 7.componentDidUpdate组件更新完成')
  34. }
  35. render() {
  36. console.log('Counter 3.render挂载')
  37. return (
  38. <div>
  39. <p>{this.state.number}</p>
  40. <button onClick={this.handleClick}>+</button>
  41. </div>
  42. )
  43. }
  44. }
  45. ReactDOM.render(<Counter />, document.getElementById('root'));

运行结果:
image.png

2、实现生命周期

2.1 实现componentWillMount和componentDidMount方法

修改react-dom.js类组件挂载方法:

注意componentDidMount方法需要在挂载后执行,所以先放到dom属性上;
image.png

此时已经挂载,直接执行componentDidMount方法;
image.png

2.2 实现shouldComponentUpdate方法

因为更新发生在setState触发,修改一下setState方法调用的addState方法:
image.png

image.png

修改Component.js中的Updater类的updateClassComponent方法修改为updateComponent方法。修改逻辑:
image.png

shouldUpdate方法实现:

  1. // Component.js
  2. /**
  3. * 判断组件是否需要更新
  4. * @param {*} classInstance 组件实例
  5. * @param {*} nextState 新的状态
  6. */
  7. function shouldUpdate(classInstance, nextState) {
  8. // 不管组件要不要刷新,组件的state属性一定会改变
  9. classInstance.state = nextState
  10. // 如果有shouldComponentUpdate并且值为false就不需要更新了,否则更新
  11. if (classInstance.shouldComponentUpdate && !classInstance.shouldComponentUpdate(classInstance.props, classInstance.state)) {
  12. return
  13. }
  14. // 组件更新
  15. classInstance.forceUpdate()
  16. }

2.3 实现compoentWillUpdate方法和componentDidUpdate方法

因为compoentWillUpdate在更新渲染dom之前触发,componentDidUpdate在渲染dom后触发,所以代码逻辑要写在forceUpdate中
image.png

3、实现效果

验证一下:和原生一模一样
image.png

4、源码

源码地址:https://gitee.com/linhexs/react-write/tree/6.life-cycle-old/