当值相等时,React 钩子 useState setValue 仍然重新渲染一次

IT技术 javascript reactjs frontend react-hooks
2021-05-22 13:22:00

我有下面的示例代码:

function App() {
  console.log("render");
  const [val, setVal] = React.useState(0);
  return (
    <div className="App">
      <h1>{val}</h1>
      <button onClick={() => setVal(12)}>Update with same value</button>
    </div>
  );
}

当我多次单击一个按钮时,控制台会记录 3 次并显示“render”消息。对我来说,应该只有 2 次:

  • 1 用于第一次渲染

  • 2 用于从 val 0 到 12 的更新(单击按钮时)

从这一次开始,它不应重新渲染,因为相同的值 (12) 已更新为 val。

但是为什么会出现3次呢?这意味着尽管更新了相同的值,它仍然会重新渲染一次。

哪位知道的请解释一下,先谢谢了。

P/S:我发现它只会在值改变时导致额外的重新渲染,然后用相同的值更新

function App() {
  console.log("render");
  const [val, setVal] = useState(4);
  return (
    <div className="App">
      <h1>{val}</h1>
      <button onClick={() => {
        setVal(val => val + 1)
      }}>Update</button>
      <button onClick={() => {
        setVal(val => val)
      }}>Update with same value</button>
    </div>
  );
}

当第一次点击第二个按钮时,没有重新渲染调用,但是如果你点击第一个按钮然后第二个按钮,第二个按钮会导致 1 次额外的重新渲染

2个回答

这个线程可能对你有帮助:React: Re-Rendering on Setting State - Hooks vs. this.setState

此外,您可以在此处查看第二段,其中说:

请注意,在退出之前,React 可能仍需要再次渲染该特定组件。这不应该是一个问题,因为 React 不会不必要地“深入”到树中。如果您在渲染时进行昂贵的计算,您可以使用 useMemo 优化它们。

React 无法猜测 render() 的输出不会改变:它必须再次 render() 并将结果与​​之前的 render() 进行比较。

然后神奇的事情发生了:如果没有差异,DOM 不会更新;如果存在差异,它会尝试仅根据需要创建/销毁元素,因为这是昂贵的部分,而不是运行 render() — 好吧,它不应该如此。

更改状态通常会触发对 render() 的调用(不一定是 DOM 修改)——但如果您想控制该行为,请定义shouldComponentUpdate.


注意:这适用于非钩子组件。但是,我不知道钩子的行为与常规组件的行为略有不同:似乎您期望setState在值不变时不触发渲染是正确的- 请参阅 Yash Joshi 的回答。