反应挂钩切换setState

时间:2020-04-20 00:26:37

标签: 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>
  );
}

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

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>
  );
}

哪个是正确的?据我了解,由于设置状态为异步,第二个可能不起作用,如果我多次单击该按钮,则可能无法获得正确的状态

1 个答案:

答案 0 :(得分:4)

第一个是正确的:

setShow(s => !s);

尽管第二个在这种情况下有效,但这是不正确的:

// bad code
setShow(!show);

为什么?

设置状态是异步的-但这的真正含义是将设置状态推迟到重新渲染。

一个例子:

const [myNum, setMyNum] = useState(0)

const handleUpdate = () => {
  setMyNum(myNum + 1)
}

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

const [myNum, setMyNum] = useState(0)

const handleUpdate = () => {
  setMyNum(myNum + 1)
  setMyNum(myNum + 1)
}

您可能认为myNum现在是2,但不是,仍然是1。

之所以会这样,是因为myNum的值在重新渲染之前不会改变,因此您实际上是在编写:

const handleUpdate = () => {
  setMyNum(0 + 1)
  setMyNum(0 + 1)
}

因此,如果您依赖于先前的值,您应该始终提供设置状态的功能。

这正常工作:

const handleUpdate = () => {
  setMyNum(p => p + 1)
  setMyNum(p => p + 1)
}

myNum现在是2。

即使只设置一次该值,也应保持良好的操作习惯。当您的应用变得复杂并且随时可以通过几种不同的操作设置状态时,您不想被几个月前写的从未想到的事情所吸引。