Reactjs 为什么 useEffect 有时会在每个挂载/渲染上运行而不是第一次运行 [英] Reactjs why useEffect sometimes runs on every mount/render instead of just first

查看:31
本文介绍了Reactjs 为什么 useEffect 有时会在每个挂载/渲染上运行而不是第一次运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 App.js 的路由中有一个 useEffect

I have a useEffect in my Routes in App.js

    <Switch>
      <Route exact path={['/en', '/fr']} component={HomePage} />
      <Route path={['/en/*', '/fr/*']}>
        <Route path="/:lang/*" component={DefaultLanguage} />

在同一个文件(App.js)中,我们有这样的组件(使用 react-localize-redux):

in the same file(App.js) we have the component like so (using react-localize-redux):

const DefaultLanguage = withLocalize(
  ({ activeLanguage, setActiveLanguage, ...props }) => {
    useEffect(() => {
      console.log('setting active language');
      setActiveLanguage(props.match.params.lang);
    }, []);
    return <></>;
  }
);

问题是我点击的每个链接都运行 setActiveLanguage 即使我把 [] 设置为只在第一次渲染时运行(因为这是我唯一一次关心从 URL 设置语言)我已经在应用程序的其他部分也有这个问题.根据我的理解,useEffect 不应在每次安装组件时运行,除非其依赖项发生变化,但我似乎缺少一个细节.

The problem is every link i click runs setActiveLanguage even though i put [] to make it only run on first render (because that's the only time I care about setting language from URL) I've had this issue in other parts of the app as well. From my understanding useEffect shouldn't run everytime the component is mounted unless its dependancies change, but it seems I'm missing a detail.

推荐答案

您是正确的,将空数组传递给 useEffect 将阻止它在后续 渲染 上运行,但是如果组件被卸载然后再次安装,这不会阻止它运行.

You are correct that passing an empty array to useEffect will stop it from running on subsequent renders, but that will not stop it from running if the component is unmounted and then mounted again.

我的猜测是,通过单击您的链接,您实际上是在卸载然后重新安装您的 DefaultLanguage 组件.

My guess is that by clicking on your links you are actually un-mounting and then re-mounting your DefaultLanguage component.

您可以通过从 useEffect 钩子返回一个清理函数来测试这一点.

You could test this by returning a cleanup function from your useEffect hook.

例如,

useEffect(() => {
      console.log('setting active language');
      setActiveLanguage(props.match.params.lang);

      return () => console.log('Unmounting');
    }, []);

如果您看到该日志,那么您就发现了问题.

If you are seeing that log, then you've found your problem.

一个快速而肮脏的解决方案可能是检查语言是否已更改,如果已更改,则进行设置.这不会解决可能不必要的挂载/卸载问题,但至少可以避免再次设置语言.

A quick and dirty solution could be to check and see if the language has changed, and if so set it. That won't address the potentially unnecessary mount/unmount but will at least avoid setting the language again.

useEffect(() => {
      if (activeLanguage !== props.match.params.lang) {
        console.log('setting active language');
        setActiveLanguage(props.match.params.lang);
      }
    }, []);

这篇关于Reactjs 为什么 useEffect 有时会在每个挂载/渲染上运行而不是第一次运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆