react-state和setState
state
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 1 };
}
// ...
}
setState
setState(updater[, callback])
- updater 可以是一個函數也可以是一個對象類型
this.setState((state, props) => stateChange);
this.setState({ count: 1 });
setState 的基本使用
- setState 的基本格式
this.setState({ count: this.state.count + 1 });
- setState 是批量更新的
class Test extends React.Component {
state = {
count: 1
};
componentDidMount() {
this.setState({
count: this.state.count + 1
});
this.setState({
count: this.state.count + 1
});
// 批量合并更新 count為2
}
render() {
return <div>{this.state.count}</div>;
}
}
- this.state 和 this.props 可能會異步更新
- 可以讓 setState()接受一個函數
- 第一個參數為 state,第二個參數為 props
class Test extends React.Component{
state = {
count : 1
}
componentDidMount(){
this.setState((state, props) => {
console.log("state,props :", state, props);
return { count: state.count + 1 };
});
this.setState((state, props) => ({
count: state.count + 1
})
this.setState((state, props) => ({
count: state.count + 1
})
// count 值為4
}
render(){
return (
<div>{this.state.count}</div>
)
}
}
- setState 并不總是立即更新組件,它會批量推遲更新
- 所以調用后立即讀取 this.state 成為隱患,可以是使用 componentDidUpdate 或者是 setState 的回調函數
this.setState(
{
count: 2
},
() => {
console.log("this.setState的回調函數");
}
);
setState 小結
1.setState 只在合成事件和鉤子函數中是異步的,在原生事件和 setTimeout 中是同步的
2.setState 的異步并不是說內部異步代碼是實現的,其本身的代碼是同步的.
- 合成事件和鉤子函數的調用在 setState 調用之前, 導致在合成事件和鉤子函數中沒法拿到 setState 更新后的值,形成了所謂的"異步",當然可以通過的第二個參數 setState(partialState,callback)中的 callback 拿到更新后的結果
總結:屬于原生 js 執行的空間,setState 就是同步,被 react 處理過的就是異步
3.setState 的批量更新中,
- 在原生 js 事件和 setTimeout 中,不會批量更新
- 在 react 中
- 如果對同一個值進行多次 setState,setState 的批量更新會對其進行覆蓋,取最后一次的執行,
- 如果是對不同的值,在更新時會其進行合并批量更新