官网:https://reactjs.org/docs/react-component.html
先看一个例子:
constructor(){
this.state={
val:0,
}
}
componentDidMount(){
this.setState({val:this.state.val+1});
console.log(this.state.val);
this.setState({val:this.state.val+1});
console.log(this.state.val);
setTimeout(()=>{
this.setState({val:this.state.val+1});
console.log(this.state.val);
this.setState({val:this.state.val+1});
console.log(this.state.val);
},0);
}
结果: 0,0,2,3
setState
只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout
中都是同步的。
setState()
setState(updater[, callback]) //我深深的怀疑官网写错了,应该是 setState(updater, [callback])
1.第一个参数:updater
函数
(state, props) => stateChange
例子:
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
当然 你也可以传一个对象而不是函数:
this.setState({counter: 2});
2.第二个参数:callback (
可选参数)
修改完成,回调。
React 官方更推荐使用 componentDidUpdate()
,而不是 callback
来监听 update 事件
状态:
setState()
will always lead to a re-render unless shouldComponentUpdate()
returns false
. If mutable objects are being used and conditional rendering logic cannot be implemented in shouldComponentUpdate()
, calling setState()
only when the new state differs from the previous state will avoid unnecessary re-renders.
使用componentDidUpdate
或setState
回调(setState(updater, callback)
),其中任何一个都保证在应用更新后触发。
1 不要使用 this.state
来直接修改 state
2 状态更新可能是异步的
3 状态更新是一个合并的过程
4单向数据流, state 都是由一个特定的组件所拥有的
源码:
case UpdateState: {
const payload = update.payload;
let partialState;
if (typeof payload === 'function') {
// Updater function
if (__DEV__) {
enterDisallowedContextReadInDEV();
if (
debugRenderPhaseSideEffects ||
(debugRenderPhaseSideEffectsForStrictMode &&
workInProgress.mode & StrictMode)
) {
payload.call(instance, prevState, nextProps);
}
}
partialState = payload.call(instance, prevState, nextProps);
if (__DEV__) {
exitDisallowedContextReadInDEV();
}
} else {
// Partial state object
partialState = payload;
}
if (partialState === null || partialState === undefined) {
// Null and undefined are treated as no-ops.
return prevState;
}
// Merge the partial state and the previous state.
return Object.assign({}, prevState, partialState);
}
附:三种方式获取更新后的state
1、回调函数
2、settimeout
3、promise封装