Источник: Nuances of Programming
В процессе создания всё более сложных и крупных приложений в React начинаешь понимать, что управление общим состоянием всего приложения невозможно только при помощи класса React.Component, использующего конструктор constructor() с вызовом setState(). Нам нужен контейнер состояний, такой как Redux, чтобы можно было запустить его в разных средах, централизовав состояние/логику приложения, и легко проводить отладку.
Итак, вот некоторые особенности Redux, с которыми вы, наверняка, уже сталкивались, но не совсем понимали, что и как они делают… и, конечно же, примеры.
Мы рассмотрим 15 малоизвестных особенностей Redux:
- Ключевые принципы Redux.
- Компромиссы при использовании Redux вместо Flux.
- Различие между mapStateToProps и mapDispatchToProps.
- Диспетчеризация действия в редукторе.
- Диспетчеризация действия при загрузке.
- Сброс состояния в Redux.
- Различие между React context и React-Redux.
- Создание AJAX-запроса в Redux.
- Лучший способ получить доступ в хранилище Redux.
- Зачем использовать константы?
- Зачем использовать ownProps в mapStateToProps() и mapDispatchToProps()?
- Различие между call() и put() в Redux-Saga.
- Различие между Redux-Saga и Redux-Thunk.
- Установка начального состояния в Redux.
1. Ключевые принципы Redux
В основе работы Redux лежат 3 главных принципа:
1️⃣ Единственный источник истины
Это означает, что состояние всего приложения содержится в хранилище в виде дерева объектов.
Преимущества:
- Единственное дерево состояния облегчает процесс отладки и проверки приложения.
- Позволяет сохранять состояние приложения для ускорения процесса разработки.
- Облегчает создание универсальных и крупномасштабных приложений.
Пример:
2️⃣ Состояние только для чтения
Состояние можно изменить только при отправке действия.
Так как все состояния централизованы и происходят последовательно друг за другом, то нет необходимости следить за состоянием гонки.
Пример:
3️⃣ Изменения выполняются чистыми функциями
Вы пишите редукторы, чтобы указать на изменение состояния при помощи действий.
Так как редукторы являются чистыми функциями, вы можете контролировать порядок их вызова, отправлять дополнительные данные или даже писать переиспользуемые редукторы.
Пример:
2. Преимущества Flux перед Redux
Flux — это шаблон, Redux — библиотека. При использовании Redux вам придется пойти на некоторые компромиссы:
- Придется избегать мутаций. Этогоможно добиться при помощи пакетов redux-immutable-state-invariant и Immutable.js.
- Тщательно выбирать пакеты. УRedux есть точки расширения, такие как мидлвары и расширители хранилища, содержащие обширную экосистему пакетов.
- Отсутствует удобная интеграция с Flow.
3. Различие между mapStateToProps() и mapDispatchToProps()
> mapStateToProps()
Это утилита, которая помогает вашему компоненту обновлять состояние (которое обновляется некоторыми другими компонентами). Эта функция передается в качестве первого аргумента в connect и впоследствии будет вызываться каждый раз при изменении состояния хранилища Redux.
Пример:
> mapDispatchToProps()
Это утилита, которая помогает вашему компоненту запускать событие действия (отправка действия, которое может вызвать изменение состояния приложения). Компонент получает [dispatch](https://react-redux.js.org/api/connect#dispatch) по умолчанию.
Пример:
4. Диспетчеризация действия в редукторе
Причиной для внесения этого пункта в мой список стал следующий популярный вопрос со Stackoverflow: “Можно ли отправить действие в самом редукторе?” Отвечая на этот вопрос, скажу лишь одно:
Отправка действия в редуктор — это анти-шаблон.
5. Диспетчеризация действия при загрузке
Вы можете отправить действие во время загрузки с помощью метода componentDidMount(), проверяя данные в методе render().
Пример:
6. Сброс состояния в Redux
Лучший способ — использовать исходный редуктор и передать действие редуктору, созданному при помощи combineReducers().
Пример:
7. Использование символа @ в функции декораторе connect
В JavaScript символ @ используетсядляобозначения декораторов, при помощи которых выдобавляете или видоизменяете классы и свойства.
8. Различие между React context и React-Redux
> React context
React context предоставляет способ направлять данные через дерево компонентов без необходимости передачи свойств сверху вниз вручную на каждом уровне.
Используется для небольших приложений, тогда как Redux сам по себе обеспечивает более основательное и мощное управление состояниями.
> React-Redux
React-Redux — это официальная библиотека, которая предоставляет привязки React для Redux. Она позволяет компонентам React считывать данные из хранилища Redux и отправлять туда действия для обновления данных.
9. Создание AJAX-запроса в Redux
AJAX позволяет отправлять асинхронные HTTP-запросы для передачи и извлечения данных с сервера.
Чтобы выполнить вызов AJAX в Redux, можно использовать мидлвар redux-thunk для определения асинхронных действий.
Пример:
10. Лучший способ получить доступ в хранилище Redux
Лучший способ — использовать функцию connect() с применением шаблона функций высшего порядка. Это позволяет отобразить креаторы состояния и действия в компонент и автоматически передать их, когда обновится хранилище.
Пример:
11. Зачем использовать константы?
Использование констант позволяет легко находить все случаи применения конкретной выполняемой функции в проекте. Кроме того, они помогут избежать большого количества ошибок ReferenceError.
Пример:
12. Зачем использовать ownProps в mapStateToProps() и mapDispatchToProps()?
ownProps является необязательным параметром, который мы добавляем в mapStateToProps() или mapDispatchToProps()в качестве второго аргумента. Используйте его в том случае, если вашему компоненту нужны данные из его собственных свойств для извлечения данных из хранилища.
Пример:
Согласно документации:
Вам необязательно включать значения из ownProps в объект, возвращаемый из mapStateToProps. connect автоматически объединит разные источники свойств в конечный набор.
13. Различие между call() и put() в Redux-Saga
redux-saga — это библиотека, которая призвана облегчить управление побочными эффектами приложения, а также сделать их более эффективными в выполнении, легкими в тестировании и способствующими улучшению обработки ошибок.
> call()
Проще говоря, вы используете call() для создания описания эффекта, который дает команду мидлвару для вызова промиса. После этого мидлвар вызывает функцию и проверяет ее результат.
> put()
Что же касается функции put(), то она создает эффект, который дает мидлвару команду отправить действие в хранилище.
Таким образом, call() и put() являются функциями креаторов эффектов.
14. Различие между Redux-Saga и Redux-Thunk
Мидлвар Redux Thunk позволяет написать креатор действия, который возвращает функцию вместо действия. Thunk можно использовать для задержки отправки действия или для отправки только при выполнении определенного условия.
- Thunk использует промисы, тогда как Saga — генераторы.
- Thunk прост в использовании, да и промисы хорошо знакомы. Saga/Генераторы более мощные, но требуют изучения.
15. Установка начального состояния в Redux
Существуют 2 способа:
1.Использовать метод createStore, который принимает в качестве второго аргумента необязательное значение preloadedState.
Пример:
2.Использовать явную проверку внутри редуктора.
Пример:
function myReducer(state = someDefaultValue, action)
Надеюсь, я понятно объяснил эти 15 особенностей Redux. Интересно, а знали ли вы о них?
Читайте также:
Читайте нас в телеграмме и vk
Перевод статьи Vaibhav Khulbe: Demystifying lesser-known Redux terms and features (With examples)