1.代码
import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function fetchData() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('获取ajax数据');
}, 2000);
});
}
class Welcome extends Component {
constructor(props) {
console.log("constructor", props);
super(props);
this.state = {
color: props.color
};
}
componentWillMount() {
console.log("componentWillMount");
// this.setState({color: "yellow"}); 1.在componentWillMount中setState
// setTimeout(() => { /***************************************************/
// this.setState({ color: "green" }); /******2.在componentWillMount中延时setState**********/
// }, 1000); /***************************************************/
}
componentDidMount() {
console.log("componentDidMount");
// this.setState({ color: "yellow" }); 3.在componentDidMount中setState
}
componentWillReceiveProps(nextProps, nextState) {
console.log("componentWillReceiveProps", nextProps, nextState);
if (nextProps.color !== this.state.color) {
this.setState({ color: nextProps.color });
}
}
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate", nextProps, nextState);
return true;
}
componentWillUpdate(nextProps, nextState) {
console.log("componentWillUpdate", nextProps, nextState);
}
componentDidUpdate(prevProps, prevState) {
console.log("componentDidUpdate", prevProps, prevState);
}
changeColor = () => {
this.setState({color: "#ddd"})
}
render() {
console.log("render", this.state.color);
return (
<div style={{ background: this.state.color }}>
<h1>react 旧的生命周期</h1>
<p>{this.state.color}</p>
<button onClick={this.changeColor}>内部change color</button>
</div>
);
}
}
class App extends Component {
state = {
currentColor: "red",
colorIndex: 0
};
changeColor = () => {
let colors = ["red", "yellow", "blue", "green", "pink"];
let { colorIndex } = this.state;
colorIndex = ++colorIndex % 5;
this.setState({
currentColor: colors[colorIndex],
colorIndex
});
};
render() {
let { currentColor } = this.state;
return (
<div className="App">
<Welcome color={currentColor} />
<hr />
<button onClick={this.changeColor}>外部change color</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
2. 输出结果
1.直接输出
constructor {color: "red"}
componentWillMount
render red
componentDidMount
2.componentWillMount中改变state
- ①在componentWillMount中改变state,即将代码注释1处打开,setState先执行,改变完了state,然后才执行render,可见在这方法里同步地设置状态将不会触发重渲。
constructor {color: "red"}
componentWillMount
render yellow
componentDidMount
- ②在componentWillMount中延时改变state,即将代码注释2处打开, 因为延时,render在setState之前执行,执行完了,会触发一次重新渲染(render)。可见在这方法里异步地设置状态会触发重渲。
constructor {color: "red"}
componentWillMount
render red
componentDidMount
shouldComponentUpdate {color: "red"} {color: "green"}
componentWillUpdate {color: "red"} {color: "green"}
render green
componentDidUpdate {color: "red"} {color: "red"}
- ③在componentWillMount中使用async,await(发送ajax),将componentWillMount改成如下形式
async componentWillMount() {
console.log("componentWillMount");
let result = await delay()
this.setState({ color: "green" });
}
输出结果如下,也会触发一次重新渲染(render),what the Fuck!!!
我一直以为不会重新渲染,那为什么ajax请求不建议放在componentWillMount中,网上搜了一大堆,都说不能触发重新render,莫不是智障?????
constructor {color: "red"}
componentWillMount
render red
componentDidMount
result 获取ajax数据
shouldComponentUpdate {color: "red"} {color: "green"}
componentWillUpdate {color: "red"} {color: "green"}
render green
componentDidUpdate {color: "red"} {color: "red"}
3.componentDidMount中改变state
- ①在componentDidMount中改变state,即将代码注释3处打开,可见componentDidMount会重新触发一次render,注意这里没有ajax的异步请求,直接setState就会重新渲染!!!
constructor {color: "red"}
componentWillMount
render red
componentDidMount
shouldComponentUpdate {color: "red"} {color: "yellow"}
componentWillUpdate {color: "red"} {color: "yellow"}
render yellow
componentDidUpdate {color: "red"} {color: "red"}
4.改变父组件传入值,从而改变子组件state
点击父组件改变颜色按钮,改变父组件传入的props的值,查看结果
componentWillReceiveProps => shouldComponentUpdate => componentWillUpdate => render => componentDidUpdate
componentWillReceiveProps {color: "yellow"} {}
shouldComponentUpdate {color: "yellow"} {color: "yellow"}
componentWillUpdate {color: "yellow"} {color: "yellow"}
render yellow
componentDidUpdate {color: "red"} {color: "yellow"}
5.改变子组件state值
点击子组件改变颜色按钮,改变子组件state值,查看结果
shouldComponentUpdate => componentWillUpdate => render => componentDidUpdate
shouldComponentUpdate {color: "red"} {color: "#ddd"}
componentWillUpdate {color: "red"} {color: "#ddd"}
render #ddd
componentDidUpdate {color: "red"} {color: "yellow"}