【问题标题】:Reactjs why useEffect sometimes runs on every mount/render instead of just firstReactjs 为什么 useEffect 有时会在每个挂载/渲染上运行而不是首先运行
【发布时间】:2019-10-05 05:30:15
【问题描述】:

我在 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 <></>;
  }
);

问题是我单击的每个链接都会运行 setActiveLanguage,即使我将 [] 设置为仅在第一次渲染时运行(因为这是我唯一关心从 URL 设置语言的时间)我在其他部分也遇到过这个问题的应用程序以及。据我了解,useEffect 不应该在每次安装组件时都运行,除非它的依赖项发生变化,但我似乎遗漏了一个细节。

【问题讨论】:

    标签: reactjs react-redux react-router-v4 use-effect react-localize-redux


    【解决方案1】:

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

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

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

    例如,

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

    如果您看到该日志,那么您已经找到了问题。

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

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

    【讨论】:

    • 我错过的细节是渲染和安装之间的区别。我不认为带有[] 的useEffect 无论如何都会再次运行。这很有帮助。
    猜你喜欢
    • 2021-06-23
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    相关资源
    最近更新 更多