React 钩子切换 setState

pea*_*ove 5 reactjs react-hooks

到目前为止,我看到了两种处理切换的方法

首先,根据之前的状态设置状态

export default function App() {
  const [show, setShow] = useState(false);
  const handleClick = () => {
    setShow(s => !s);
  };
  return (
    <div>
      <div>show: {String(show)}</div>
      <button onClick={handleClick}>BTN</button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

其次,直接将状态作为参数传递

export default function App() {
  const [show, setShow] = useState(false);
  const handleClick = () => {
    setShow(!show);
  };
  return (
    <div>
      <div>show: {String(show)}</div>
      <button onClick={handleClick}>BTN</button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

哪一个是正确的?根据我的理解,第二个可能不起作用,因为设置状态是异步的,如果我多次单击按钮,它可能无法获得正确的状态

JMa*_*ine 11

第一个是正确的:

setShow(s => !s);
Run Code Online (Sandbox Code Playgroud)

虽然第二个在这种情况下有效,但它是不正确的:

// bad code
setShow(!show);
Run Code Online (Sandbox Code Playgroud)

为什么?

设置状态是异步的——但这真正意味着设置状态被推迟到重新渲染。

一个例子:

const [myNum, setMyNum] = useState(0)

const handleUpdate = () => {
  setMyNum(myNum + 1)
}
Run Code Online (Sandbox Code Playgroud)

如果我们调用这个handleUpdate函数,新的值myNum会增加 1。这工作正常,但是这个呢:

const [myNum, setMyNum] = useState(0)

const handleUpdate = () => {
  setMyNum(myNum + 1)
  setMyNum(myNum + 1)
}
Run Code Online (Sandbox Code Playgroud)

你可能认为myNum现在是 2,但事实并非如此,它仍然是 1。

发生这种情况是因为 的值在myNum重新渲染之前不会改变,所以您基本上是这样写的:

const handleUpdate = () => {
  setMyNum(0 + 1)
  setMyNum(0 + 1)
}
Run Code Online (Sandbox Code Playgroud)

这就是为什么如果您依赖于前一个值,您应该始终提供一个函数来设置状态。

这正常工作:

const handleUpdate = () => {
  setMyNum(p => p + 1)
  setMyNum(p => p + 1)
}
Run Code Online (Sandbox Code Playgroud)

myNum 现在是 2。

即使您只设置一次该值,您也应该保持良好的实践。当您的应用程序变得复杂并且几个不同的操作可能随时设置状态时,您不希望被几个月前编写的一些您从未想过会重要的东西所吸引。