state
React组件的数据分为两种:props
和state
,props
是组件的对外接口,state
是组件的内部状态。状态state
与属性props
十分相似,但是状态是私有的,完全受控于当前组件,无论props
还是state
的改变,都可能引发组件的重新渲染。
由于React
不能直接修改传入的props
,所以需要记录自身数据变化,就要使用state
。
组件的state
,相当于组件的记忆,其存在意义就是被改变,每一次通过this.setState
函数修改state
就改变了组件的状态,然后通过渲染过程把这种变化体现出来。
【正确使用state】
1、不要直接更新状态,构造函数是唯一能够初始化 this.state
的地方。
如果直接修改this.state的值,虽然事实上改变了组件的内部状态,但只是野蛮地修改了state,但没有驱动组件进行重新渲染。而this.setState()
函数所做的事情,就是先改变this.state
的值,然后驱动组件重新渲染。
// Wrong
this.state.comment = 'Hello';
// Correct
this.setState({comment: 'Hello'});
2、状态更新可能是异步的
setState
是异步更新,而不是同步更新,下面是一个例子。
setYear(){
let {year} = this.state
this.setState({
year: year + 10 //新值
})
console.log(this.state.year)//旧值
}
setYear(){
setTimeout(() => {
this.setState({
year: year + 10 //新值
})
console.log(this.state.year)//新值
})
}
因为this.props
和 this.state
可能是异步更新的,不应该依靠它们的值来计算下一个状态。
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
要修复它,要使用第二种形式的 setState()
来接受一个函数而不是一个对象。 该函数将接收先前的状态作为第一个参数,将此次更新被应用时的props
做为第二个参数:
// Correct
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
3、状态更新合并
可以调用 setState()
独立地更新它们,但React将多个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
。
4、回调函数
由于setState
是异步更新的,如果需要确定setState
更新后,再进行某些操作,可以使用setState
的回调函数。
this.setState({ val:value }, () => {
this.refs.editInput.focus()
})