0

我在 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 不应该在每次安装组件时都运行,除非它的依赖项发生变化,但似乎我错过了一个细节。

4

1 回答 1

2

你是正确的,传递一个空数组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);
      }
    }, []);
于 2019-05-18T03:05:16.450 回答