小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
二刷react官方文档:State & 生命周期 的时候 新有不少感悟 记录下来
1.State 的更新会被合并,这个合并是浅合并
啥是浅合并?一步一步来看
当你调用 setState() 的时候,React 会把你提供的state对象合并到当前的 state。
例如,你的 state 包含几个独立的变量:
constructor(props) {
super(props);
this.state = {
posts: [],
comments: []
};
}
然后你可以分别调用 setState() 来单独地更新它们:
componentDidMount() {
fetchPosts().then(response => {
this.setState({
posts: response.posts
});
});
fetchComments().then(response => {
this.setState({
comments: response.comments
});
});
}
这里的合并是浅合并,所以 this.setState({comments}) 完整保留了 this.state.posts, 但是完全替换了 this.state.comments。(跟浅拷贝的感觉差不多~但是用法不同)
2.数据是向下流动的
state是局部的对象
先来看看为什么state是局部的/是封装的
不管是父组件或是子组件都无法知道某个组件是有状态的还是无状态的,并且它们也并不关心它是函数组件还是 class 组件。 所以除了拥有并设置了它的组件,其他组件都无法访问state对象。
因为state对象可以向下“流动”,所以子组件可以访问到父组件的state
(虽然state的属性就像类内定义的变量一样 其他组件无法访问) 但是!组件可以选择把它的 state 作为 props 向下传递到它的子组件中:(“流动”嘛!)
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
子组件在props中接收参数date~
function FormattedDate(props){
return <h2>It is {props.date.toLocaleTimeString()}.</h2>
}
这通常会被叫做“自上而下”或是“单向”的数据流。任何的 state 总是所属于特定的组件,而且从该 state 派生的任何数据或 UI 只能影响树中“低于”它们的组件。
如果你把一个以组件构成的树想象成一个 props 的数据瀑布的话,那么每一个组件的 state 就像是在任意一点上给瀑布增加额外的水源,但是它只能向下流动。
举个例子
为了证明每个组件都是真正独立的,我们可以创建一个渲染三个 Clock 的 App 组件:
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>
);
}
}
function App() {
return (
<div>
<Clock />
<Clock />
<Clock />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
每个 Clock 组件都会单独设置它自己的计时器并且更新它。
每个组件都是独立的!
最后 我们要清楚——
在 React 应用中,组件是有状态组件还是无状态组件属于组件实现的细节,它可能会随着时间的推移而改变。(state啥的不是你想给加就加了么~在构造器中添加
this.state={shuxing: xxx};即可)你可以在有状态的组件中使用无状态的组件,反之亦然。(那肯定奥)
小结
最大的感触就是
- 组件对state的更新是浅合并的
- 每一个组件的state 就像是任一点上给瀑布(把组件构成的树想象成一个props的数据瀑布)增加额外的水源 且state只能向下“流动”