我有一个简单的 React 应用程序,其中的 index.js 文件如下所示:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
由于某种原因,这会导致
App
组件渲染两次(由 App
中的控制台日志证明)。当我删除 <React.StrictMode>
时,它仅渲染一次:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
//<React.StrictMode>
<App />
//</React.StrictMode>
);
当我用谷歌搜索这个时,我发现了这个(https://react.dev/reference/react/StrictMode),上面写着:
你的组件将重新渲染额外的时间来查找不纯渲染引起的错误。 您的组件将重新运行 Effects 一段额外的时间,以查找因缺少 Effect 清理而导致的错误。
有什么办法可以防止
StrictMode
造成的双重渲染吗?例如,App
组件的子组件包含由setTimeout
设置的计时器。由于双重渲染,该计时器被创建两次,这会产生不必要的副作用。 <-- Can this be fixed or worked around?
StrictMode 是一种发展辅助工具。它指出了必须配备清理功能以恢复副作用的组件,并将它们保留为纯组件。
它检查组件的纯度,并提供一些在开发过程中进行早期检测的方法。它对生产没有任何影响。
纯组件是对于相同输入返回相同输出的组件,无论调用次数如何。纯函数就像一个公式。对于相同的输入,无论调用多少次,它都会给出相同的输出。
让我们采用公式:
y = 2x;
如果 x = 2,则 y 将始终为 4,无论调用了多少次。因此它是纯净的。
让我们在 React 中创建一个函数,它的功能与公式相同。每次调用该组件都会产生给定值的两倍。总是。因此它也是纯净的。
function FormulaOne(x) {
return 2 * x;
}
但是,让我们看以下不同的情况。
通过在开发中渲染下面的应用程序,我们期望它给出 1 作为输出,但它给出 2。这是由于 React 为了测试其纯度而双重安装了同一组件。但是,如果该组件是纯组件,它将返回相同的预期结果。因此,双重安装对于检测错误(如果有)非常有用。
export default function App() {
return (
<>
<FormulaTwo x={1} />
</>
);
}
let mulfactor = 0;
function FormulaTwo({ x }) {
mulfactor++;
return <>{mulfactor * x}</>;
}
现在为了解决上面讨论的不纯组件,它所产生的副作用必须在组件的每个卸载事件上恢复。这就是组件需要清理功能的地方。
让我们通过下面的清理函数来修复不纯的组件。从现在开始,这个函数将作为一个纯粹的函数。使用相同的输入多次调用它将会得到相同的输出。现在,当我们运行它时,即使双重安装仍在发生,我们也会得到 1。清理函数会恢复每个卸载事件的副作用,从而保持函数的纯净。
import { useEffect } from 'react';
export default function App() {
return (
<>
<FormulaTwo x={1} />
</>
);
}
let mulfactor = 0;
function FormulaTwo({ x }) {
mulfactor++;
useEffect(() => {
return () => {
mulfactor--;
};
});
return <>{mulfactor * x}</>;
}