# 状态和生命周期
我们有一个时钟组件,它接受外部参数传入的时间,将其显示。
function Clock(props) {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {props.date.toLocaleTimeString()}.</h2>
</div>
);
}
export default Clock;
我们需要定时的调用render()
来更新显示的事件。
import Clock from "./components/Clock";
const root = ReactDOM.createRoot(document.getElementById('root'));
function tick() {
root.render(<Clock date={new Date()} />);
}
setInterval(tick, 1000);
理想情况下,我们希望只编写一次代码,便可以让 Clock 组件自我更新。
我们需要在 Clock 组件中添加 “state” 来实现这个功能
# 改写为 Class 组件
// src/components/Clock.jsx
import React from "react";
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
export default Clock;
# 添加 State
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
# 添加生命周期
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
// life circle
// like vue mounted
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
// like vue beforeDestory
componentWillUnmount() {
clearInterval(this.timerID);
}
// methods
tick() {
// 使用 this.setState() 来时刻更新组件 state
this.setState({
date: new Date()
});
}
// render
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
import Clock from "./components/Clock";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Clock/>);
# 正确地使用 State
# 不要直接修改 State
// 例如,此代码不会重新渲染组件
// Wrong
this.state.comment = 'Hello';
// 而是应该使用 setState():
// Correct
this.setState({comment: 'Hello'});
构造函数是唯一可以给 this.state 赋值的地方。
# State 的更新可能是异步的
出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。(运行时优化)
例如,此代码可能会无法更新计数器:
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
要解决这个问题,可以让 setState()
接收一个函数而不是一个对象。这个函数用上一个 state 作为第一个参数。
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
由于函数的闭包,所以此时参数的值得以被保存。
# State 的更新会被合并
当你调用 setState()
的时候,React 会把你提供的对象合并到当前的 state。
故而我们可以分别调用 setState()
来单独地更新它们
componentDidMount() {
fetchPosts().then(response => {
this.setState({
posts: response.posts // change post
});
});
fetchComments().then(response => {
this.setState({
comments: response.comments // change comments
});
});
}