为什么即使旧状态等于新状态,使用相同值调用 useState 的 setter 也会随后触发组件更新?

Dan*_*tov 6 javascript reactjs react-dom react-hooks

仅当状态值因上次更新而实际更改时,才会出现此问题。

在下面的例子中,当第一次点击按钮时,“setState”被调用了一个新值(12),并且发生了一个组件更新,这是可以理解的。

当我第二次单击同一个按钮时,将状态设置为相同的 12 值会导致组件重新运行(重新渲染),为什么会发生这种情况是我的主要问题。

任何后续设置为 12 相同值的 setState 都不会触发组件更新,这也是可以理解的。12 === 12 所以不需要更新。

那么,为什么第二次单击按钮时会发生更新?

export default function App() {
  const [state, setState] = useState(0);

  console.log("Component updated");

  return (
    <div className="App">
      <h1>Hello CodeSandbox {state}</h1>
      <button onClick={() => setState(12)}>Button</button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

代码沙盒示例

Den*_*ash 5

主要问题是,为什么登录函数组件主体会导致 3 个日志"Component updated"

答案隐藏在React 文档中

如果您将 State Hook 更新为与当前状态相同的值,React 将退出而不渲染子项或触发效果。

没有什么新东西,但是:

请注意,在退出之前,React可能仍需要再次渲染该特定组件。这不应该是一个问题,因为 React 不会不必要地“深入”到树中。

但请注意useEffectAPI 定义:

将在渲染提交到屏幕后运行。

如果您记录更改,useEffect您只会注意到预期的两个“B”日志,这正是提到的救助行为示例:

const App = () => {
  const [state, setState] = React.useState(0);

  useEffect(() => {
    console.log("B");
  });

  console.log("A");

  return (
    <>
      <h1>{state}</h1>
      <button onClick={() => setState(42)}>Click</button>
    </>
  );
};
Run Code Online (Sandbox Code Playgroud)

组件将有一个额外的“救助”调用App(额外的“A”日志),React 不会“深入”并且不会更改现有的 JSX 或状态(不会记录额外的“B”)。

编辑 Q-65037566-检查渲染