Reactjs 为什么 useEffect 有时会在每个 mount/render 而不是第一个上运行
Reactjs why useEffect sometimes runs on every mount/render instead of just first
我在 App.js
的路线中有一个 useEffect
<Switch>
<Route exact path={['/en', '/fr']} component={HomePage} />
<Route path={['/en/*', '/fr/*']}>
<Route path="/:lang/*" component={DefaultLanguage} />
在同一个文件中(App.js)我们有这样的组件(使用 react-localize-redux):
const DefaultLanguage = withLocalize(
({ activeLanguage, setActiveLanguage, ...props }) => {
useEffect(() => {
console.log('setting active language');
setActiveLanguage(props.match.params.lang);
}, []);
return <></>;
}
);
问题是每次 link 我都单击 运行s setActiveLanguage,即使我将 []
设置为仅在第一次渲染时 运行 (因为这是唯一一次我关心从 URL) 设置语言 我在应用程序的其他部分也遇到过这个问题。根据我的理解,useEffect 不应该 运行 每次安装组件时除非它的依赖关系发生变化,但我似乎遗漏了一个细节。
你是正确的,将一个空数组传递给 useEffect
将在随后的 呈现 中阻止它从 运行,但这不会阻止它从 运行 如果组件被卸载然后再次安装。
我的猜测是,通过单击您的链接,您实际上是 un-mounting 然后 re-mounting 您的 DefaultLanguage
组件。
您可以通过从 useEffect
挂钩返回清理函数来测试它。
例如,
useEffect(() => {
console.log('setting active language');
setActiveLanguage(props.match.params.lang);
return () => console.log('Unmounting');
}, []);
如果您看到该日志,那么您就找到了问题。
一个快速而肮脏的解决方案可能是检查并查看语言是否已更改,如果已更改则进行设置。这不会解决可能不必要的 mount/unmount 但至少会避免再次设置语言。
useEffect(() => {
if (activeLanguage !== props.match.params.lang) {
console.log('setting active language');
setActiveLanguage(props.match.params.lang);
}
}, []);
我在 App.js
的路线中有一个 useEffect <Switch>
<Route exact path={['/en', '/fr']} component={HomePage} />
<Route path={['/en/*', '/fr/*']}>
<Route path="/:lang/*" component={DefaultLanguage} />
在同一个文件中(App.js)我们有这样的组件(使用 react-localize-redux):
const DefaultLanguage = withLocalize(
({ activeLanguage, setActiveLanguage, ...props }) => {
useEffect(() => {
console.log('setting active language');
setActiveLanguage(props.match.params.lang);
}, []);
return <></>;
}
);
问题是每次 link 我都单击 运行s setActiveLanguage,即使我将 []
设置为仅在第一次渲染时 运行 (因为这是唯一一次我关心从 URL) 设置语言 我在应用程序的其他部分也遇到过这个问题。根据我的理解,useEffect 不应该 运行 每次安装组件时除非它的依赖关系发生变化,但我似乎遗漏了一个细节。
你是正确的,将一个空数组传递给 useEffect
将在随后的 呈现 中阻止它从 运行,但这不会阻止它从 运行 如果组件被卸载然后再次安装。
我的猜测是,通过单击您的链接,您实际上是 un-mounting 然后 re-mounting 您的 DefaultLanguage
组件。
您可以通过从 useEffect
挂钩返回清理函数来测试它。
例如,
useEffect(() => {
console.log('setting active language');
setActiveLanguage(props.match.params.lang);
return () => console.log('Unmounting');
}, []);
如果您看到该日志,那么您就找到了问题。
一个快速而肮脏的解决方案可能是检查并查看语言是否已更改,如果已更改则进行设置。这不会解决可能不必要的 mount/unmount 但至少会避免再次设置语言。
useEffect(() => {
if (activeLanguage !== props.match.params.lang) {
console.log('setting active language');
setActiveLanguage(props.match.params.lang);
}
}, []);