Недавно я познакомился с API React Hooks. Это кажется довольно интересным и может полностью изменить то, как мы делаем приложения React.

Вступление:

ПРИМЕЧАНИЕ. Это альфа-версия, поэтому, пожалуйста, пока не используйте ее в крупномасштабных производственных приложениях. Но я не думаю, что так долго будет.

Вы можете найти документацию здесь. Вкратце, API призван помочь следующим образом:

  • Сокращение использования классов, поскольку они, кажется, сбивают с толку программистов, которые широко использовали их на других языках.
  • Разделение проблем в коде компонента на основе логики, а не методов жизненного цикла - больше никакого дублирования кода в componentDidMount и componentDidUpdate
  • Изолированное использование логики с отслеживанием состояния между компонентами без необходимости использования компонентов более высокого порядка или рендеринга.

Реализация:

Нам нужно придумать лучший пример приложения для проверки новых стеков, поскольку список дел становится очень простым и не всегда охватывает все элементы, которые мы хотим опробовать. Однако в этом случае я больше всего хотел проверить хук useReducer(). Было бы неплохо иметь возможность повторно использовать большую часть кода редуктора, который у нас уже есть в наших приложениях. Итак, список задач у меня работает.

Базовая настройка:

Можно использовать обычный create-react-app и довольно быстро начать работу, но я подозревал, что могут быть некоторые несоответствия версий библиотеки. Итак, я пошел с нуля с нуля. Действительно, возникла проблема с работой HMR (требуется как минимум v4.6.0):

  • Установите менеджер пакетов, например yarn (или npm), если он еще не установлен
  • Инициализируйте приложение с yarn initgit init)
  • Сделайте папки public и src в каталоге приложения
  • Добавьте .gitignore с обычными элементами, такими как node_modules и dist
  • Добавьте базовый index.html в папку public:
{  "presets": ["@babel/env", "@babel/preset-react"] }
  • Добавьте App.js в папку src (оставьте пока комментарий к части списка дел. Мы раскомментируем их, как только сделаем их. Всегда лучше сначала запустить приложение):
  • Добавьте scripts к package.json:
"scripts": {
  "start": "webpack-dev-server --mode development",
  "build": "webpack --mode production"
}
  • Запустите приложение с yarn run start и убедитесь, что приложение с HMR работает должным образом на localhost:3000.

Список дел:

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

Можно иметь еще более простую логику для редуктора списка дел, используя везде только индексы, но по личному опыту я обнаружил, что использование идентификаторов безопаснее.

Переходя к хукам, в этом примере мы будем использовать useReducer и useState. Вы можете найти их документацию здесь и здесь.

  1. useReducer определяется следующим образом:
const [state, dispatch] = useReducer(reducer, initialState);

Это может показаться очень знакомым людям, которые какое-то время использовали редукторы в приложениях React. state - нормальное состояние компонента; dispatch используется для вызова обновления state; reducer определяет логику обновления; initialState объявляет значение для инициализации state.

В нашем примере родительский компонент, содержащий логику списка дел, объявляет state с использованием useReducer и передает функции CRUD, которые будут использовать dispatch, дочерним компонентам.

2. useState определяется следующим образом:

const [state, setState] = useState(initialState);

Здесь state может быть любой переменной, которую в противном случае вы могли бы объявить с помощью this.state в конструкторе. initialState - начальное значение для этой переменной. setState работает аналогично this.setState, но зависит от объявленной здесь переменной. В сочетании с ловушкой useEffect (в основном для обработки операций монтирования и обновления; не используется в этом примере), в идеале после этого объявления, это сгруппировало бы всю логику, связанную с переменной state, в одном месте в коде компонента. Если его нужно использовать в нескольких компонентах, эту логику также можно обернуть в настраиваемый крючок.

В нашем примере операции CRUD над задачами обрабатываются реквизитами, которые передаются дочерним элементам от родительского компонента. Но локальную обработку обновления текста задачи может выполнять useState.

В обработке обновлений text и mode было очень мало логики. В случае реальных приложений к ним будет привязана дополнительная логика, например, наличие различных разрешений на доступные режимы и требование проверки аутентификации перед редактированием. В таких случаях было бы разумно переместить логику редактирования mode и text в настраиваемые хуки и использовать их во всех компонентах.

Стиль и бег:

В качестве последнего штриха давайте добавим здесь немного стиля нашим компонентам.

И мы закончили. Вот как выглядит приложение:

Код этого примера доступен по адресу: https://github.com/nsuthar0914/react-hooks-webpack-hmr

Наблюдения:

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

С нетерпением жду возможности попробовать еще и посмотреть, как это работает с клиентами GraphQL.

- Нирадж Сутхар