[英]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.