gio*_*gim 7 javascript reactjs react-hooks
经过一番尝试,我发现严格模式下会出现以下问题。如果有人能解释原因,我会很感兴趣。
以这个简单的例子为例,在渲染内部我只是安排一个更新状态的超时:
例子:
let firstRender = true; // Normally I would use ref but I was playing with example
export default function App() {
let [data, setData] = React.useState({ name: 'Nick' });
// Schedule a timeout on first render
if (firstRender) {
setTimeout(() => {
console.log('Running');
setData((ps) => ({
...ps,
name: 'Paul',
}));
}, 1000);
}
console.log('Running render');
firstRender = false;
return (
<div>
<h1>{data.name}</h1>
<p>Start editing to see some magic happen :)</p>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
如果您在没有严格模式的情况下运行此示例,那么一秒钟后您将在屏幕上看到“Paul”,正如我所期望的那样。
如果您使用严格模式,屏幕上将始终显示“Nick”。知道为什么吗?
注意:似乎使用useRef而不是全局变量firstRender也可以在严格模式下修复此问题。发生这种情况似乎是因为ref在第一次渲染中设置了它,并且它的值也被丢弃了(另请参阅答案)。
这是因为严格模式故意调用函数组件主体两次(在开发模式下)以帮助发现意外的副作用。
\n在第二次调用时,您的firstRender变量是false这样的,因此您的 setTimeout 不会运行。
需要注意的是,第二次调用不仅仅是像状态更新那样的重新渲染。这是整个组件主体的第二次调用。状态未保留。React 调用组件函数一次,丢弃结果,然后第二次调用它以获取输出。
\n来自文档:
\n\n\n由于上述方法可能会被多次调用,因此重要的是它们不包含副作用。
\n
\n\n严格模式可以\xe2\x80\x99t自动为您检测副作用,但它可以通过使副作用更具确定性来帮助您发现它们。这是通过有意两次调用以下函数来完成的:
\n
\n\n\n
\n- 功能组件体
\n
| 归档时间: |
|
| 查看次数: |
704 次 |
| 最近记录: |