Хуки React упростили управление состоянием и побочными эффектами в функциональных компонентах. Они позволяют нам использовать состояние и другие функции React без написания класса.
Хуки полагаются на замыкания JavaScript. Если вы не знакомы с замыканиями в JavaScript, я бы порекомендовал посмотреть это видео, чтобы узнать об этом.
При использовании хуков могут возникать ситуации, когда вы сталкиваетесь с устаревшими замыканиями, и способ решить проблему — правильно установить зависимости для хуков.
Когда замыкание фиксирует устаревшее значение, это называется устаревшим замыканием.
Давайте рассмотрим различные сценарии с использованием разных хуков, когда вы можете столкнуться с этой ситуацией:
useEffect :
Внутри компонента DisplayCount хук useEffect регистрирует значение счетчика каждые 2 секунды.
Откройте песочницу и попробуйте нажать на кнопку увеличения. Вы заметите, что счетчик увеличивается в пользовательском интерфейсе, но когда вы посмотрите на консоль, вы заметите, что она отображает Count is: 0, несмотря на то, что он увеличивался несколько раз.
В чем проблема?
Во время первого рендеринга count был инициализирован 0, а после монтирования компонента setIntervalвнутри useEffectрасписание log()функция. Здесь закрытие log() фиксирует значение счетчика как 0.
Позже, даже если значение счетчика увеличивается, вызовы закрытия log() по-прежнему используют значение счетчика как 0 из исходного рендеринга. Здесь log() становится устаревшим замыканием.
Решение, чтобы избежать этой ситуации, состоит в том, чтобы сделать следующее:
После установки счетчика в качестве зависимости замыкание обновляется в useEffect, как только счетчик изменяется.
useCallback:
Внутри компонента Counter есть два метода увеличения счетчика: один обернут с помощью useCallback, а другой — это обычная стрелочная функция, обновляющая счетчик.
Откройте песочницу и попробуйте нажать на обе кнопки. Вы заметите, что счетчик увеличивается в пользовательском интерфейсе для обычной кнопки Увеличить, как обычно, но когда вы нажмете кнопку Увеличить с обратным вызовом и посмотрите в консоль, вы заметите, что она отображает значение счетчика из обратного вызова: 0, несмотря на то, что что он был увеличен несколько раз.
В чем проблема?
Во время первого рендеринга count был инициализирован 0, а после монтирования компонента функция внутри useCallback зафиксировала значение счетчика как 0. >
Позже, даже после увеличения значения счетчика, сформированное закрытие все еще использует значение счетчика как 0 из исходного рендеринга. Здесь мы снова сталкиваемся с устаревшим закрытием.
Решение, чтобы избежать этой ситуации, состоит в том, чтобы сделать следующее:
После установки счетчика в качестве зависимости замыкание обновляется в useCallback, как только счетчик изменяется.
Заключение
Нам нужно убедиться, что мы правильно устанавливаем зависимость при использовании хуков, чтобы избежать ситуации устаревшего закрытия.
Кроме того, есть несколько подобных сценариев, которые могут произойти и с другими хуками, которые мы добавим в следующих статьях.
Если вам понравилась эта история, нажмите кнопку 👏 и поделитесь ею, чтобы другие тоже могли ее найти! Кроме того, не стесняйтесь оставлять комментарии ниже.
Groww Engineering публикует технические анекдоты, новейшие технологии и лучшие способы решения распространенных проблем программирования. Вы можете подписаться здесь, чтобы получать последние обновления.
Мы нанимаем. Посмотреть вакансии здесь.