Reactjs, почему useEffect иногда запускается при каждом монтировании / рендеринге, а не просто сначала - PullRequest
0 голосов
/ 18 мая 2019

У меня есть useEffect в моих маршрутах в App.js

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

в том же файле (App.js) у нас есть такой компонент (с использованием response-localize-redux):

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

Проблема в том, что каждая ссылка, по которой я щелкаю, запускает setActiveLanguage, хотя я поставил [], чтобы она работала только при первом рендеринге (потому что это единственный раз, когда я забочусь о настройке языка из URL). У меня возникла эта проблема в других частях. приложения тоже. Насколько я понимаю, useEffect не должно запускаться каждый раз, когда компонент монтируется, пока не меняются его зависимости, но, похоже, мне не хватает детали.

1 Ответ

1 голос
/ 18 мая 2019

Вы правы, что передача пустого массива в useEffect остановит его запуск при последующих рендерингах , но это не остановит его запуск, если компонент отключен, а затем снова подключен.

Я предполагаю, что, кликнув по ссылкам, вы фактически де-монтируете, а затем заново монтируете свой DefaultLanguage компонент.

Вы можете проверить это, вернув функцию очистки из useEffecthook.

Например,

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);
      }
    }, []);
...