前置知识:https://www.yuque.com/linhe-8mnf5/fxyxkm/sifrm7
1、老生命周期的使用
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
class Counter extends React.Component {
static defaultProps = { name: '计数器' }
constructor(props) {
super(props)
this.state = { number: 0 }
console.log('Counter 1.constructor初始化')
}
// eslint-disable-next-line react/no-deprecated
componentWillMount() {
console.log('Counter 2.conponentWillMount组件将要挂载')
}
componentDidMount() {
console.log('Counter 4.conponentDidMount挂载完成')
}
handleClick = () => {
this.setState({
number: this.state.number + 1
})
}
shouldComponentUpdate(nextProps, nextState) {
console.log('Counter 5.shouldComponentUpdate询问组件是否需要更新?')
return nextState.number % 2 === 0; // 偶true 基 false
}
//WARNING! To be deprecated in React v17. Use componentDidUpdate instead.
// eslint-disable-next-line react/no-deprecated
componentWillUpdate(nextProps, nextState) {
console.log('Counter 6.componentWillUpdate组件将要更新')
}
componentDidUpdate(prevProps, prevState) {
console.log('Counter 7.componentDidUpdate组件更新完成')
}
render() {
console.log('Counter 3.render挂载')
return (
<div>
<p>{this.state.number}</p>
<button onClick={this.handleClick}>+</button>
</div>
)
}
}
ReactDOM.render(<Counter />, document.getElementById('root'));
运行结果:
2、实现生命周期
2.1 实现componentWillMount和componentDidMount方法
修改react-dom.js类组件挂载方法:
注意componentDidMount方法需要在挂载后执行,所以先放到dom属性上;
此时已经挂载,直接执行componentDidMount方法;
2.2 实现shouldComponentUpdate方法
因为更新发生在setState触发,修改一下setState方法调用的addState方法:
修改Component.js中的Updater类的updateClassComponent方法修改为updateComponent方法。修改逻辑:
shouldUpdate方法实现:
// Component.js
/**
* 判断组件是否需要更新
* @param {*} classInstance 组件实例
* @param {*} nextState 新的状态
*/
function shouldUpdate(classInstance, nextState) {
// 不管组件要不要刷新,组件的state属性一定会改变
classInstance.state = nextState
// 如果有shouldComponentUpdate并且值为false就不需要更新了,否则更新
if (classInstance.shouldComponentUpdate && !classInstance.shouldComponentUpdate(classInstance.props, classInstance.state)) {
return
}
// 组件更新
classInstance.forceUpdate()
}
2.3 实现compoentWillUpdate方法和componentDidUpdate方法
因为compoentWillUpdate在更新渲染dom之前触发,componentDidUpdate在渲染dom后触发,所以代码逻辑要写在forceUpdate中
3、实现效果
验证一下:和原生一模一样
4、源码
源码地址:https://gitee.com/linhexs/react-write/tree/6.life-cycle-old/