state可以通过this.state.{属性}的方式直接获得,但当修改state时,往往有很多陷阱需要注意。下面介绍常见的三种陷阱。
一、不能直接修改state
直接修改state,组件并不会重新触发render,例如:
//错误
this.state.title = "React";
正确的修改方式是使用setSate();
//正确
this.setState({title:"React"});
二、state的更新是异步的
很多开发刚开始没有注意到 setState 是异步的。如果你修改一些 state ,然后直接查看它,你会看到之前的 state 。这是 setState 中最容易出错的地方,如:
import React,{Component} from "react"
class ChangeState extends Component{
constructor(props){
super(props)
this.state={
count:0,
}
}
handleClick = (event)=>{
this.setState({
count:this.state.count+1
});
//取到的是旧值,打印的结果是0,不是1
console.info(this.state.count);
}
render(){
return (
<div>
<div>点击次数(显示的是最新的值){this.state.count}</div>
<div>
<button onClick={this.handleClick}>次数</button>
</div>
</div>
);
}
}
export default ChangeState
另外,需要注意的是props的更新也是异步的。
如果需要在 setState 后直接获取修改后的值,可以使用回调函数,setState 方法接收一个 function 作为回调函数。这个回调函数会在 setState 完成以后直接调用,这样就可以获取最新的 state 。如:
handleClick = (event)=>{
this.setState({
count:this.state.count+1
},()=>{
//在setState的回调函数里取值,就能取到最新的值,打印的结果是 1
console.info(this.state.count);
});
//取到的是旧值,打印的结果是0,不是1
console.info(this.state.count);
}
三、state的更新是一个合并的过程
当调用setState修改组件状态时,只需要传入发生改变的state,而不是组件完整的state,因为组件state的更新是一个合并的过程。例如,一个组件的状态为:
this.state={
title : 'React',
content : 'React is an wonderful JS library',
}
当只需要修改title时,将修改后的title传给setState即可:
this.setState({title : 'Reactjs'});
React会合并新的title到原来的组件状态中,同时保留原来的状态content,合并后的state为:
{
title : 'Reactjs',
content : 'React is an wonderful JS library',
}