State 的生命周期
这是前面文档中例子:
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocalTimeString()}.</h2>
</div>
);
ReactDOM.render(
element,
document.getElementById('root');
);
}
setInterval(tick, 1000);
把这个例子包装成一个名为 clock 的 component,这个 component 会显示时间并每隔一秒钟更新一次。
function Clock(props) {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {props.date.toLocalTimeString()}.</h2>
</div>
);
}
function tick() {
ReactDOM.render(
<Clock date={new Date()} />,
document.getElementById('root')
);
}
setInterval(tick, 1000);
但包装之后,它的封装性并不好。我们希望这个 component 可以这样使用:
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
为了实现一个可以这样使用的 component, 我们需要给 Clock 加上 state。state 和 props 类似,但是它是 component 私有的,并且完全被它控制。另外,component 使用 class 来定义,才能够使用 state。
把一个 Function 转化为 Class
需要创建一个 ES6 class, 并且是继承 React.Component 的。同时需要实现一个 render 方法。
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocalTimeString()}.</h2>
</div>
);
}
}
为这个 Class 添加 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.toLocalTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
为 Class 增加生命周期相关的方法
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocalTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
State 相关注意事项
- 不能直接修改,要通过
setState
来进行修改。 - 修改可能是异步的,所以后面的计算不能依赖于前面设置的 state,因为更新可能尚未完成。
- 不需要更新 state 的所有成员,可以只更新需要更新的,没有被更新的和新更新的会自动合并。
Component 的数据是往下流动的
Component 是树状结构,父节点向子节点传递数据,所以说数据是往下流动的。