React的生命周期
2019-10-11 本文已影响0人
sweetBoy_9126
使用js实现四个常用的生命周期
let app = document.getElementById("app");
// create div
let div = document.createElement("div");
div.style.border = "1px solid red";
let state = 0;
// render/update
div.innerHTML = `
<p>${state}</p>
<button>1</button>
<button>die</button>
`;
// mount div
app.appendChild(div);
div.querySelector("button").onclick = () => {
state += 1;
// update/render div
div.querySelector("p").innerText = state;
};
div.querySelectorAll("button")[1].onclick = () => {
div.querySelector("button").onclick = null;
div.querySelectorAll("button").onclick = null;
div.remove();
div = null; // destroy div
};
react
class Baba extends React.Component {
constructor() {
super();
this.state = {
hasChild: true
};
}
killSon() {
this.setState({
hasChild: false
});
}
talkSon() {
this.setState({
word: "爸爸说的话"
});
}
render() {
return (
<div>
<button onClick={() => this.killSon()}>kill son</button>
<button onClick={() => this.talkSon()}>跟儿子说句话</button>
// 在父组件中将子组件销毁
{this.state.hasChild ? <App word={this.state.word} /> : null}
</div>
);
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
n: 0
};
console.log("创建 App");
}
onClick() {
this.setState({
n: this.state.n + 1
});
}
componentWillMount() {
console.log("将要挂载 App");
}
render() {
// update
console.log("填充/更新 App的内容");
return (
<div className="App">
爸爸:
{this.props.word}
<br />
{this.state.n}
<button onClick={() => this.onClick()}>+1</button>
</div>
);
}
componentDidMount() {
console.log("mount App 完毕");
}
componentWillUpdate() {
console.log("update App 之前");
}
componentDidUpdate() {
console.log("update App 之后");
}
// 销毁组件,必须在父组件中将其销毁
componentWillUnmount() {
console.log("儿子被杀死前");
}
// 如果有父组件传来的数据就会触发当前生命周期
componentWillReceiveProps() {
console.log("爸爸说话了");
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Baba />, rootElement);
案例运行地址:https://codesandbox.io/s/laughing-fire-pbc5m
react可以做的事情
-
请求数据(ajax)
推荐在componentDidMount
里
原因:为了性能的需要,Fiber
有了调度render
执行顺序的能力,所以componentWillMount
执行变得不确定;
在constructor
中你不能使用setState
-
更新数据
setState
1). 不能在mount
之前setState
2). 不能在render
里setState
3). 不能再将要更新和更新完成的钩子里setState
推荐在onclick
,componentDidMount
和componentWillReceiveProps
里setState
-
手动判断是否更新(shouldComponentUpdate)
允许我们手动的判断是否进行组件更新,避免不必要的更新(如果不想更新就return false
)
实例:
在state
里添加一个x
,我们在页面中不显示x
,但是有一个按钮可以修改x
,每一次点击按钮x
后面会多加一个感叹号,正常情况下我们更新x会触发componentWillUpdate
,render
和componentDidUpdate
,如果我们想阻止更新的话只需要在shouldComponentUpdate
里判断就可以了
this.state = {
n: 0,
x: "不展示"
};
updateX() {
this.setState({
x: this.state.x + "!"
});
}
render() {
// update
console.log("填充/更新 App的内容");
return (
<div className="App">
爸爸:
{this.props.word}
<br />
{this.state.n}
<button onClick={() => this.onClick()}>+1</button>
<button onClick={() => this.updateX()}>updateX</button>
</div>
);
}
shouldComponentUpdate(nextProps, nextState) {
if (this.state.n === nextState.n) {
return false;
} else {
return true;
}
}
在用户点击一个按钮调用setState的时候会调用哪几个钩子?
shouldComponentUpdate
,componentWillUpdate
,render
,componentDidUpdate