Улучшение вашей ментальной модели использования

Хуки появились в React несколько месяцев назад, и вокруг них было много волнения с точки зрения выяснения того, как их лучше всего использовать, передовых практик и того, как они соотносятся с текущими концепциями в React и жизненном цикле.

Многие разработчики React знакомы с жизненным циклом компонентов React и такими хуками, как:

Когда вы пытаетесь понять ловушку useEffect, естественно захотеть сопоставить ее с методами жизненного цикла, которые мы уже знаем. На первый взгляд useEffect выглядит как комбинация componentDidMount и componentDidUpdate.

Хотя на первый взгляд это может быть полезным способом взглянуть на него, он может быть не самым точным.

Вместо того чтобы думать о том, «что я хочу делать, когда я подключаюсь или обновляю», полезнее спросить:

От каких значений зависит этот эффект?

Чтобы лучше понять, откуда взялась идея useEffect = componentDidMount + componentDidUpdate, мы сначала рассмотрим типичный компонент на основе классов, который выполняет некоторую выборку данных.

Когда компонент монтируется впервые, мы получаем данные для идентификатора, который был передан в качестве опоры. Когда компонент обновляется, поскольку многие вещи, помимо изменения пропуска идентификатора, могут вызвать запуск этого метода, мы хотим убедиться, что идентификатор действительно изменился - иначе какой-то плохой сервер получит DDoS-атаку с кучей вызовов API, которые нам не нужно.

Хотя хуки жизненного цикла componentDidMount и componentDidUpdate с компонентами на основе классов являются обычными местами для выполнения запроса на основе свойства, тот факт, что компонент монтируется или обновляется, не действительно то, что нас беспокоит.

Что нас волнует: «от каких данных зависит запрос?»

Прежде чем смотреть, как справиться с этим с помощью useEffect, давайте быстро рассмотрим API useEffect:

  • Принимает функцию
  • Если он возвращает функцию, он выполнит очистку при размонтировании компонента.
  • Имеет необязательный второй аргумент для передачи данных, от которых он зависит

Одна из ключевых вещей, о которых следует помнить, - это важность второго аргумента, React Docs подробно описывает это, но вкратце:

  • Если оставить поле пустым - он будет запускаться при каждом рендере.
  • Если мы передадим пустой массив - он будет выполняться только при монтировании компонента, а не при каких-либо обновлениях
  • Если мы передадим значение - оно будет выполняться при изменении любого из этих значений.
  • Если вы используете react-hooks eslint plugin (и вы должны это сделать) - отсутствие зависимостей для вашего useEffect приведет к предупреждению.

В версии на основе классов выполнение вызовов API кажется крайне необходимым - когда вызывается этот метод, я хочу проверить, изменилось ли / как значение, и если оно изменилось - я хочу вызвать метод.

Неважно, часто ли компонент создается или обновляется. Что нас на самом деле волнует, так это «изменились ли ценности, которые меня волнуют?».

До появления хуков componentDidMount и componentDidUpdate были лучшими инструментами для работы в то время.

С версией на основе ловушки мы можем выразить это намерение более декларативно: «Я хочу получать данные при изменении идентификатора»

Как определить, от чего зависит эффект?

Плагин eslint может направить вас в правильном направлении, но его краткая версия: «есть ли переменная, которая влияет на то, как мы запускаем эффект?» Если да, добавьте его в зависимости.

Чтобы продемонстрировать это, давайте добавим в наш поиск дополнительный параметр запроса:

Несмотря на то, что мы добавили filter в строку запроса выборки, мы не добавили его в зависимости useEffect. При обновлении фильтра мы не будем вызывать API для других обновлений, и он будет запускаться только при изменении идентификатора.

Исправить это достаточно просто - просто добавьте фильтр в список зависимостей данных для useEffect.

Как видите, для правильного использования useEffect в этом случае нам все равно, монтируется ли компонент, обновляется или где он находится в жизненном цикле - нас действительно волнует то, что data зависит ли этот эффект от.

useEffect - очень полезный инструмент, который можно добавить к нашему набору инструментов при работе с React, но он также может быть одним из наиболее сложных приемов для понимания.

Надеюсь, этот пост поможет прояснить ситуацию немного лучше, но если вам интересно более глубокое погружение, обязательно ознакомьтесь с постом Дэна Абрамова Полное руководство по использованию эффекта