繁体   English   中英

每次更改 + 渲染后是否更新 DOM

[英]is the DOM updated after each change + render

我试图完全理解 DOM 协调、虚拟 DOM、组件渲染和效果挂钩之间的关系。 我正在使用以下代码,它返回“三”状态。 但是中间状态“一”和“二”是否总是打印在 DOM 上,即使是眨眼的几分之一秒?

export default function App() {
  const [status, setStatus] = React.useState("zero");

  const handleChangeStatus = () => {
    setStatus("one");
  };

  useEffect(() => {
    if (status === "one") {
      setStatus("two");
    }
  }, [status]);

  useEffect(() => {
    if (status === "two") {
      setStatus("three");
    }
  }, [status]);

  return (
    <div>
      <div id={status}>{status}</div>
      <br />
      <button onClick={handleChangeStatus}>Change statuses</button>
    </div>
  );
}

一旦点击,

简而言之, useEffect挂钩在内容刷新到 DOM 后的渲染周期结束时运行。 每个useEffect挂钩按照声明的顺序运行每个渲染周期。 每个useEffect挂钩根据效果回调中依赖项的值在不同的渲染周期上将 state 更新排入队列。

但是中间状态“一”和“二”是否总是打印在 DOM 上,即使是眨眼的几分之一秒?

对,他们是。 每个 state 更新都在不同的渲染周期中排队,因此每个更新都会被处理,并且协调后的差异会刷新到 DOM 并渲染。 React 框架的目标是大约 60fps 的刷新率,或者每个渲染周期大约 17ms。 基本数学:1s/60render * 1000ms/1s = 1000ms/60render = 16.6667ms/render。 我敢说,17ms 几乎是难以察觉的。

如果你考虑到这一点并乘以 3 个触发的 state 更新,我们谈论的是大约 50ms 的 React 完成工作。 仍然几乎无法察觉。 作为参考,人类眨眼的平均时间似乎在 100-150ms 之间

您还可以使用几个额外的useEffect挂钩非常轻松地自行测试这一点,注销 state 更新和渲染周期。 记下日志 output 中的时间戳。

 function App() { const [status, setStatus] = React.useState("zero"); const handleChangeStatus = () => { setStatus("one"); }; React.useEffect(() => { if (status === "one") { setStatus("two"); } }, [status]); React.useEffect(() => { if (status === "two") { setStatus("three"); } }, [status]); React.useEffect(() => { console.log("Status updated", status); }, [status]); React.useEffect(() => { console.log("Component rendered") }) return ( <div> <div id={status}>{status}</div> <button onClick={handleChangeStatus}>Change statuses</button> </div> ); } const rootElement = document.getElementById("root"); const root = ReactDOM.createRoot(rootElement); root.render( <React.StrictMode> <App /> </React.StrictMode> );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script> <div id="root" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM