简体   繁体   English

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

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

I'm trying to fully understand the relations among DOM reconciliation, virtual DOM, component rendering and effect hook.我试图完全理解 DOM 协调、虚拟 DOM、组件渲染和效果挂钩之间的关系。 I'm using the following code, which returns a status of "three".我正在使用以下代码,它返回“三”状态。 But are the intermediate statuses "one" and "two" always printed on the DOM, even for a blinky fraction of a second?但是中间状态“一”和“二”是否总是打印在 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>
  );
}

once clicked,一旦点击,

Simply put, the useEffect hook runs at the end of the render cycle after content has been flushed to the DOM.简而言之, useEffect挂钩在内容刷新到 DOM 后的渲染周期结束时运行。 Each useEffect hook runs each render cycle in the order they are declared.每个useEffect挂钩按照声明的顺序运行每个渲染周期。 Each useEffect hook enqueues a state update on a different render cycle based on the dependency's value in the effect callback.每个useEffect挂钩根据效果回调中依赖项的值在不同的渲染周期上将 state 更新排入队列。

But are the intermediate statuses "one" and "two" always printed on the DOM, even for a blinky fraction of a second?但是中间状态“一”和“二”是否总是打印在 DOM 上,即使是眨眼的几分之一秒?

Yes, they are.对,他们是。 Each state update is enqueued in a different render cycle, so each update will be processed and the reconciled diff flushed to the DOM and rendered.每个 state 更新都在不同的渲染周期中排队,因此每个更新都会被处理,并且协调后的差异会刷新到 DOM 并渲染。 The React framework aims for about a 60fps refresh rate, or, about 17ms per render cycle. React 框架的目标是大约 60fps 的刷新率,或者每个渲染周期大约 17ms。 The basic math: 1s/60render * 1000ms/1s = 1000ms/60render = 16.6667ms/render.基本数学:1s/60render * 1000ms/1s = 1000ms/60render = 16.6667ms/render。 17ms is nearly imperceptible I dare say.我敢说,17ms 几乎是难以察觉的。

If you take this into account and multiply by the 3 triggered state updates, we're talking about around 50ms for just React doing the work.如果你考虑到这一点并乘以 3 个触发的 state 更新,我们谈论的是大约 50ms 的 React 完成工作。 That's still nearly imperceptible.仍然几乎无法察觉。 For reference, it seems the average time for a human to blink is between 100-150ms .作为参考,人类眨眼的平均时间似乎在 100-150ms 之间

You can also very easily test this out for yourself with a couple extra useEffect hooks logging out the state updates and render cycles.您还可以使用几个额外的useEffect挂钩非常轻松地自行测试这一点,注销 state 更新和渲染周期。 Take note of the timestamps in the log output.记下日志 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.

相关问题 ReactJS - 渲染调用,但DOM未更新 - ReactJS - render called, but DOM not updated 更新每个摘要的DOM元素后,Angular如何触发回调函数 - Angular how to fire a callback function after DOM elements are updated for each digest 你如何声明一个变量,以便在每次 DOM 渲染时该值不会改变? - How do you declare a variable so that the value doesn't change on each DOM render? 每次更新 state 时如何渲染元素 - How to render element each time state is updated VueJS - V-for在数据更新后不会重新渲染,需要页面刷新才能看到更改 - VueJS - V-for doesn't re-render after data is updated and needs page refresh to see the change 更新视图(DOM)后的调用方法(在Angular 2中) - Call method after view (DOM) is updated (in Angular 2) 使用复选框后如何获取更新的 DOM? - How to get updated DOM after using checkboxes? DOM通过角度更新后的调用函数 - Call function after DOM is updated by angular 不会通过将对象推入Array来更新DOM,在推入数据后会更新数据库 - DOM is not updated by pushing object into the Array,database is updated after pushing the data 更新过滤器后如何呈现更新的列表 - How to render updated list after updating a filter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM