Open guoshuai93 opened 3 years ago
React setState 是同步还是异步方法?setState 传递对象和函数区别?
先看一个场景:
state = { count: 0 } componentDidMount () { this.setState({count: 1}) console.log(this.state.count) // 0 }
这里输出的怎么还是 0,我们不是已经更新了吗?虽然这里比较像异步的形式,其实这是由 React 框架本身的性能优化机制所导致的:将多个状态合并一起更新,而不是每次 setState 就更新一次,减少 re-render。当然你也可以理解为更新 state 是一个异步的操作。
setState
看下面这个计数器:inc 方法每次更新只会加上 1,incMulti 方法每次更新则符合预期地加上 2,为什么呢?
inc
incMulti
state
class Counter extends React.Component { constructor (props) { super(props); this.state = { count: 0 } } inc () { this.setState({count: this.state.count+1}) this.setState({count: this.state.count+1}) } incMulti () { this.setState((state, props) => ({count: state.count+1})) this.setState((state, props) => ({count: state.count+1})) } render () { return (<div> Class Demo: <p>{this.state.count}</p> <button onClick={() => this.inc()}>+</button> <button onClick={() => this.incMulti()}>+</button> </div>) } }
参照下面以 Hooks 实现的例子,和 Class 写法的组件实现的效果是一样的,只是 setCount 和 setState 的参数不一样而已。
setCount
function CounterFn() { const [count, setCount] = useState(0) function inc() { setCount(count+1) setCount(count+1) } function incMulti() { setCount(count => count+1) setCount(count => count+1) } return <div> Hooks Demo: <p>{count}</p> <button onClick={inc}>+</button> <button onClick={incMulti}>+</button> </div> }
useState
this.setState((state, props) => ({count: state.count+1}))
useRef
React setState 是同步还是异步方法?setState 传递对象和函数区别?
先看一个场景:
这里输出的怎么还是 0,我们不是已经更新了吗?虽然这里比较像异步的形式,其实这是由 React 框架本身的性能优化机制所导致的:将多个状态合并一起更新,而不是每次
setState
就更新一次,减少 re-render。当然你也可以理解为更新 state 是一个异步的操作。setState 方法传递参数为对象或者函数
Counter Class 版
看下面这个计数器:
inc
方法每次更新只会加上 1,incMulti
方法每次更新则符合预期地加上 2,为什么呢?setState
的第一个参数state
保证获取到最新的state
Counter Hooks 版
参照下面以 Hooks 实现的例子,和 Class 写法的组件实现的效果是一样的,只是
setCount
和setState
的参数不一样而已。如何能同步读取到最新状态
setState
/useState
函数式更新状态:如this.setState((state, props) => ({count: state.count+1}))
setState
支持第二个参数为完成回调函数,可以读取到最新的state
useRef
Hook:把状态保存到 ref 实例上的 current 属性上(实时改变,不触发 re-render)