DOM 生命周期
在谈React的生命周期之前,先来看看原始写法的生命周期是什么样的
let app = document.getElementById("app");
// create div
let div = document.createElement("div");
let state = 0;
div.innerHTML = `
<p>${state}</p>
<button>+</button>
<button>die</button>
`;
// mount div
app.appendChild(div);
div.style.border = "1px solid red";
div.querySelector("button").onclick = function() {
state += 1;
// update div
div.querySelector("p").innerText = state;
};
div.querySelectorAll("button")[1].onclick = function() {
// 把所有引用都清除
div.querySelector("button").onclick = null;
div.querySelectorAll("button")[1].onclick = null;
div.remove();
div = null;
// destroy div
};
上面这段代码描述了一个div的生命周期即创建销毁过程,如果搞懂了这个那React的生命周期也同理。
React 生命周期图解
下面可以尝试着用 React 的生命周期来写一遍。但是需要注意的是:React 在 16.3版本以后,将一些生命周期方法列为了不安全的生命周期。至于为什么这些生命周期方法是不安全的,React 认为这些生命周期方法经常被误解和巧妙地滥用,并且预计这种滥用可能会在异步渲染方面带来问题。在 17.0 版本将删除componentWillMount
,componentWillReceiveProps
和componentWillUpdate
。(从这个版本开始开始,只有新的“UNSAFE_”生命周期名称起作用。)
componentWillMount
componentWillReceiveProps
componentWillUpdate
React 生命周期
import React from "react";
import "./styles.css";
export default class App extends React.Component {
constructor() {
super();
this.state = {
count: 0
};
console.log("create");
}
onClick() {
this.setState({
count: this.state.count + 1
});
}
UNSAFE_componentWillMount() {
console.log("will mount");
}
componentDidMount() {
console.log("did mount");
}
UNSAFE_componentWillUpdate() {
console.log("will update");
}
componentDidUpdate() {
console.log("did update");
}
render() {
console.log("mount or update");
return (
<div className="App">
{this.state.count}
<button onClick={() => this.onClick()}>+</button>
</div>
);
}
}
/*console.log依次打印出
create
will mount
mount or update
did mount
will update
mount or update
did update
*/
总结一下,constructor
构造函数是create
的作用,组件挂载到DOM上之前会调用UNSAFE_componentWillMount
钩子,组件挂载调用render
函数,挂载完成调用componentDidMount
钩子,如果渲染的数据发生更新,也就是操作this.setState()
的时候,在更新之前会调用UNSAFE_componentWillUpdate
钩子,组件更新时再调用一次render
函数,更新完成调用componentDidUpdate
钩子。