@nana141414

Почему в обработчике старый state?

Прошу запустить этот код без strict mode, чтобы useEffect дважды не запускался и не запутал.

При запуске мы видим 2 кнопки и первый Inner. Когда нажимаю на вторую кнопку, step меняется на 2, происходит перерендер Wrapper, рендерится второй Inner. После этого запускается onUnmount первого Inner, в консоли вижу null, меняется state на "value", происходит перерендер Wrapper. Но когда после этого нажимаю на первую кнопку, step меняется на 1, происходит перерендер Wrapper, рендерится первый Inner, в консоли вижу null, а не value. Вопрос почему? Разве второй Inner не получил новый обработчик update с новым значением state после запуска onUnmount первого Inner?

export default function Wrapper() {
  const [step, setStep] = useState(1);
  const [state, setState] = useState(null);

  function update() {
    console.log(state);

    setState("value");
  }

  return (
    <div>
      {step === 1 && <Inner onUnmount={update} />}
      {step === 2 && <Inner onUnmount={update} />}

      <button onClick={() => setStep(1)}>first</button>
      <button onClick={() => setStep(2)}>second</button>
    </div>
  );
}

function Inner({ onUnmount }: any) {
  useEffect(() => {
    return () => {
      onUnmount();
    };
  }, []);

  return null;
}
  • Вопрос задан
  • 86 просмотров
Решения вопроса 1
szQocks
@szQocks
происходит перерендер Wrapper, рендерится второй Inner. После этого запускается onUnmount первого Inner, в консоли вижу null,
- происходит перерендер Wrapper, рендерится второй Inner, в который попадает функция update в котором state равен null, после запускается onUnmount первого Inner и т.д

демо

и вообще не советую в функции возврата обновлять какой-то стейт кроме глобального стора который относится ко всему приложению

если компонент размонтируется, и вызовится функция возврата из useEffect например которая обновляет какой-то там стейт верхнего компонент который там же размонтировывается, а пользователь просто открыл другую страницу в SPA, то будет сбой
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы