我读过,这useEffect
是异步的,所以 React 首先渲染和安装页面,并且只有在 useEffect 触发回调之后,所以有时我们会看到某些组件中的值变化非常快。
但是当我尝试在 useEffect 回调中使用自己创建的“sleep-for-3-seconds”时,React 会等到 3 秒过去,然后才渲染并安装页面,所以我看到空白页 3 秒。我们还可以注意到延迟 3 秒后快速变化的值。我不明白为什么会发生,因为 useEffect 回调应该在渲染和安装页面后运行。
你能解释一下为什么会这样吗?
代码沙箱: 链接
代码:
import { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
const [state, setState] = useState(1200000000);
useEffect(() => {
let start = new Date().getTime();
let end = start;
while (end < start + 3000) {
end = new Date().getTime();
}
setState(3);
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>Value is : {state}</div>
</div>
);
}
我读过,这
useEffect
是异步的,所以 React 首先渲染和装载页面,并且只有在useEffect
触发回调之后,所以有时我们会看到某些组件中的值变化非常快。
正确的。这是记录在这里:
传递给 useEffect 的函数将在渲染提交到屏幕后运行。
在这里
效果时间
与
componentDidMount
and不同componentDidUpdate
,该函数在延迟事件期间在layout和paintuseEffect
之后触发。
(他们的重点)
继续你的问题:
但是当我尝试在 useEffect 回调中使用自己创建的“sleep-for-3-seconds”时,React 会等到 3 秒过去,然后才渲染并安装页面,所以我看到空白页 3 秒。
这很奇怪,我没有看到这种行为:
const { useState, useEffect} = React;
function App() {
const [state, setState] = useState(1200000000);
useEffect(() => {
let start = new Date().getTime();
let end = start;
while (end < start + 3000) {
end = new Date().getTime();
}
setState(3);
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>Value is : {state}</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>
当我运行它时,我看到页面以初始状态值呈现1200000000
,然后三秒后我看到它使用修改后的状态值更新。
我也看不到这个更简单的例子:
const {useEffect} = React;
const Example = () => {
useEffect(() => {
const stop = Date.now() + 3000;
while (Date.now() < stop) {
// Wait (NEVER DO THIS IN REAL CODE)
}
console.log("Done waiting");
}, []);
return <div>x</div>;
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>
当我运行它时,我看到了x
组件渲染,然后三秒钟后我看到console.log
等待已经完成。
但是如果你没有看到你描述的内容,那只是因为浏览器在useEffect
调用之前没有机会实际绘制页面,尽管 React 的代码试图确保这种情况。而且由于您的代码处于忙等待状态,因此主线程与该循环相关联,并且浏览器无法更新页面显示。
但同样,我没有看到useEffect
(你会看到useLayoutEffect
)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句