回调中的useState状态更新,引用旧状态

时间:2019-09-11 09:32:30

标签: reactjs

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="wrap_content"
        android:background="@color/blue">

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="123"/>

</LinearLayout>
const Child1 = (props) => {
  
  const [obj, setObj] = React.useState({count: 1, enabled: true})
  
  const onButtonClick = () => {
    setObj({...obj, count: obj.count+1})
  }
  
  const onDelayedIncrement = () => {
    setTimeout(() => {
      setObj({...obj, count: obj.count+1})
    }, 3000) 
  }
  
  return (
    <div>
      <div>{obj.count}</div>
      <button onClick={onButtonClick}>Increment</button>
      <div><button onClick={onDelayedIncrement}>Delayed Increment</button></div>
    </div>
  );
};



ReactDOM.render(
  <Child1 />,
  document.getElementById('root')
);

在上面的代码中,如果我们单击<script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div>,然后再继续单击Delayed increment,则在执行setTimeout之后以及调用setState时,它将使用旧状态。如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

使用setState的功能形式:

setObj(currentObj => ({...currentObj, count: currentObj.count+1}))

official documentation中的更多信息。

Hooks related documentation