Функция ReactJS/NextJS useEffect() всегда вызывается два раза

#reactjs #next.js #use-effect

Вопрос:

Мой крючок useEffect() всегда вызывается дважды. Существует две зависимости: reinitializePage (если установлено значение true, будет вызван эффект использования) и corporateContext (при изменении контекста компонент должен быть обновлен).

 const [reinitializePage, setReinitializePage] = useState(true);

useEffect(() => {
  if (reinitializePage === true || corporateContext) {
      (async () => { ... })();
      setReinitializePage(false);
  }
}, [reinitializePage, corporateContext]);
 
  • Я понимаю, почему это всегда срабатывает дважды.
  • По умолчанию reinitializePage имеет значение true, поэтому useEffect сработает после изменения на false, поскольку reinitializePage является зависимостью, он сработает снова, и, поскольку в операторе if есть условие «или», а корпоративный текст всегда заполнен, он сработает снова. Если я не добавлю corporateContext в условие if, то при изменении контекста он не вызовет эффекта использования, потому что для параметра reinitializePage установлено значение false. Я не могу добавить условие «amp;amp;» в оператор if, потому что эти две зависимости не следуют друг за другом.

Итак, как я могу гарантировать, что при первом срабатывании и при повторной инициализации страницы внутри useEffect установлено значение false, как гарантировать, что после повторной инициализации страница изменится с true на false, не запускайте ее снова.

Комментарии:

1. useEffect не срабатывает в зависимости от вашего if оператора, он срабатывает, когда его зависимости — в вашем случае reinitializePage и corporateContext — меняются. Если вы не хотите, чтобы асинхронная функция запускала значение if renitializePage равно false, просто используйте amp;amp; в своем операторе if.

2. Привет, я знаю, что это срабатывает, когда меняется одна из зависимостей. И главная проблема заключается в том, что он срабатывает, когда для reinitializePage установлено значение false в методе useEffect, и сразу после этого он сработает снова. Я не могу установить для него значениеamp;amp;, потому что также существует вероятность того, что для параметра reinitializePage будет установлено значение false и будет изменен корпоративный текст.

Ответ №1:

Может быть, вы сможете хранить reinitializePage в useRef :

 const reinitializePageRef = useRef(true);

useEffect(() => {
  if (reinitializePageRef.current === true || corporateContext) {
      (async () => { ... })();

      reinitializePageRef.current = false;
  }
}, [corporateContext]);
 

В этом случае useEffect не будет обновляться, если reinitializePageRef будет изменено, поэтому, если вы установите это значение где-то в другом месте, оно может не сработать.

Ответ №2:

Вы можете использовать эффект многократного использования:

 const [reinitializePage, setReinitializePage] = useState(true);

useEffect(() => {
  if (reinitializePage === true) {
      (async () => { ... })();
      setReinitializePage(false);
  }
}, [reinitializePage]);

useEffect(() => {
  if (corporateContext) {
      (async () => { ... })();
      setReinitializePage(false);
  }
}, [corporateContext]);