三种更新阶段:
setState更新阶段
forceUpDate更新阶段
父组件render更新阶段
见图示
12.1 setState更新阶段
执行setState->shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate
执行setState:更改组件状态触发更新
shouldComponentUpdate:判断是否需要更新,返回布尔值
componentWillUpdate:执行render前的一个钩子函数,在react17中将要弃用这个钩子
render:和初始化时候执行的那个render一样,只是这里是更新值的,所以dom节点会重新更新一下
componentDidUpdate:组件更新完毕执行的钩子函数。
代码及运行结果
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script
crossorigin
src="https://unpkg.com/react@16/umd/react.development.js"
></script>
<!-- 引入react-dom用于支持react操作dom -->
<script
crossorigin
src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"
></script>
<!-- 引入babel转换jsx为js -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
class Test extends React.Component {
state = {isWash: true}
// 箭头函数点击事件
// 注意,每次setState事件发生后,render均会执行
handleClick = () => {
this.setState({isWash: !this.state.isWash});
}
// 生命周期 - 判断组件是否需要更新
shouldComponentUpdate() {
// 直接打印值会报错,下面要return布尔值
// react-dom.development.js:82 Warning: Test.shouldComponentUpdate(): Returned undefined instead of a boolean value. Make sure to return true or false.in Test
console.log('shouldComponentUpdate -> return true');
// 如果返回false,那么永远不会更新,点击无反应,不会去render
// return false;
// 如果返回true,那么会更新组件
return true;
}
// 生命周期 - 执行之前
componentWillUpdate() {
console.log('componentWillUpdate');
}
// 生命周期 - 渲染虚拟DOM
render() {
// 生命周期 - 渲染虚拟 DOM
console.log('render');
return <div onClick={this.handleClick}>老王今天{this.state.isWash ? "去" : "没去"}洗脚</div>
}
// 生命周期 - 组件更新完毕的构造函数
componentDidUpdate() {
console.log('componentDidUpdate');
}
}
ReactDOM.render(<Test name={'elendas'}/>, document.getElementById("root"));
</script>
</body>
</html>
运行结果(三次点击结果)
12.2 forceUpDate更新阶段
执行forceUpdate->componentWillUpdate->render->componentDidUpdate
代码及运行结果
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script
crossorigin
src="https://unpkg.com/react@16/umd/react.development.js"
></script>
<!-- 引入react-dom用于支持react操作dom -->
<script
crossorigin
src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"
></script>
<!-- 引入babel转换jsx为js -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
class Test extends React.Component {
// 箭头函数点击事件
handleClick = () => {
console.log('forceUpdate');
// 强制更新组件函数,如果生效,每次点击都会重新调用render函数
this.forceUpdate();
}
// 生命周期 - 执行之前
componentWillUpdate() {
console.log('componentWillUpdate');
}
// 生命周期 - 渲染虚拟DOM
render() {
// 生命周期 - 渲染虚拟 DOM
console.log('render');
return <div onClick={this.handleClick}>强制更新组件</div>
}
// 生命周期 - 组件更新完毕的构造函数
componentDidUpdate() {
console.log('componentDidUpdate');
}
}
ReactDOM.render(<Test name={'elendas'}/>, document.getElementById("root"));
</script>
</body>
</html>
运行结果(三次点击结果)
12.3 父组件render更新阶段
执行componentWillReceiveProps->shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate
代码及运行结果
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script
crossorigin
src="https://unpkg.com/react@16/umd/react.development.js"
></script>
<!-- 引入react-dom用于支持react操作dom -->
<script
crossorigin
src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"
></script>
<!-- 引入babel转换jsx为js -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// 父组件
class A extends React.Component {
state = {money: 0};
handleClick = () => {
this.setState({money: this.state.money + 100});
}
render() {
return (
<div>
<button onClick={this.handleClick}>父亲微信转账100元</button>
<B money={this.state.money}/>
</div>
)
}
}
// 子组件
class B extends React.Component {
// 子组件生命周期 - 父组件接收的props
componentWillReceiveProps(props) {
console.log('componentWillReceiveProps -> ', props);
}
// 子组件生命周期 - 判断组件是否需要更新
shouldComponentUpdate() {
console.log('shouldComponentUpdate -> return true');
return true;
// 返回false的话,money的值变动但是B组件不渲染,一直显示是0元
// return false;
}
// 子组件生命周期 - 执行之前
componentWillUpdate() {
console.log('componentWillUpdate');
}
// 子组件生命周期 - 渲染虚拟DOM
render() {
console.log('render');
return <div>儿子今天的生活费累计 {this.props.money} 元</div>
}
// 子组件生命周期 - 组件更新完毕的构造函数
componentDidUpdate() {
console.log('componentDidUpdate');
}
}
ReactDOM.render(<A/>, document.getElementById("root"));
</script>
</body>
</html>
运行结果(三次点击结果)