В настоящее время я узнаю больше о разработке React и React Native и провожу весь прекрасный и теплый летний день за просмотром уроков и руководств по Redux. Это того стоило, потому что я думаю, что понял идею Redux. Как новичок, современный разработчик Javascript, а не носитель английского языка, глоссарий Redux все еще довольно пугающий и запутанный. Все эти редукторы, действия, хранилища плюс странный синтаксис ES6 вызывают у меня желание вернуться к старому и безопасному PHP.

Поэтому я решил написать простой глоссарий (в основном для собственного использования) обо всех этих громких словах в Redux. Я не пытаюсь учить или писать о концепции Redux или о том, как ее использовать. Если Redux вам не знаком, я настоятельно рекомендую вам поискать более подходящие объяснения где-нибудь еще. Я включил некоторые ресурсы в конец моего поста.

Принципы редукса

  1. Все состояние приложения представлено одним объектом JavaScript.
  2. Это состояние (только для чтения) можно изменить, отправив действия
  3. Редьюсеры используются для описания изменений состояния

Редуктор

Редуктор — это функция, которая:

  • принимает два параметра: предыдущий state приложения и action, который нужно выполнить
  • начальное состояние определяется как значение по умолчанию для state
  • возвращает следующее состояние приложения

Редьюсер должен возвращать новый объект состояния, а не просто изменять старый, потому что в противном случае Redux будет думать, что oldState такой же, как newState. Это из-за того, как работает Javascript:

let oldObj = {};
let newObj = oldObj;
newObj.color = '#fff';
console.log(oldObj.color); // '#fff' instead of undefined
// oldObj and newObj will have a reference to same spot in memory

объединить редукторы ()

  • Приложение может иметь несколько редукторов, и combineReducers() используется для объединения всех этих функций редуктора в одну функцию редуктора.
  • Результатом использованияcombineReducers() является состояние с пространствами имен:
combineReducers({reducerA: reducerAFunction, reducerB: reducerAFunction})
// Would produce the following state object:
{
    reducerA: { /* state from reducerAFunction */},
    reducerB: { /* state from reducerBFunction */}
}

Магазин

  • Объект, который знает текущее состояние приложения
  • Вид штаб-квартиры приложения Redux
  • Один магазин на приложение

createStore (функция редуктора)

Создает хранилище с функцией reducerFunction как функцией, которая знает, что делать со всеми этими действиями.

получить состояние()

"Привет, магазин, не могли бы вы дать мне состояние?"

отправка (действие)

  • «Привет, магазин, не могли бы вы изменить текущее состояние для меня? Вы можете сделать это, сказав редюсеру выполнить это действие за меня и сказав всем этим прослушивающим компонентам, чтобы они знали об изменении состояния».
  • Отправляет действие в магазин
  • В React для этого есть привязки, поэтому, скорее всего, вы не будете его использовать. Смотри connect()

подписаться (слушатель)

  • "Привет, магазин, пожалуйста, сообщите мне, когда состояние изменится"
  • listener — это функция, которая будет вызываться после отправки действия.
  • В React для этого есть привязки, поэтому, скорее всего, вы не будете его использовать. См. Компоненты контейнера

Действие

Действие — это обычный объект Javascript со свойством type. Действие — это своего рода инструкция для редуктора, так что редьюсер знает, что он должен делать. type может быть строкой или строковой константой. Общепринято использовать строковую константу:

const THIS_IS_ACTION_TO_BE_TAKEN = 'THIS_IS_ACTION_TO_BE_TAKEN'
{
    type: THIS_IS_ACTION_TO_BE_TAKEN, // "command" to be executed
    someOtherPropForReducerToUse: 'Lorem' // other props for reducer
}

Создатель действия

Функция, которая возвращает action -объект

function actionCreatorFunction(text) {
  return {
    type: THIS_IS_ACTION_TO_BE_TAKEN,
    someOtherPropForReducerToUse: text
  }
}

Презентационные компоненты

Компоненты React, которые отображают разметку. Эти компоненты являются своего рода фиктивными компонентами, что означает, что они не знают, как они должны работать. Все, что они делают, это получают данные и функции через пропсы.

Компоненты контейнера

Компоненты-контейнеры отвечают за общение с store и передачу этой информации компонентам представления. За кулисами они отвечают за подписку на изменения состояния.

Компоненты контейнера React генерируются с помощью connect()

подключить (mapStateToProps, mapDispatchToProps) (MyOwnComponent)

Не изменяет переданный ему компонент, а возвращает новый компонент-контейнер.

mapStateToProps(state, ownProps)

  • состояние = состояние магазина
  • ownProps = реквизит <MyOwnComponent />

mapDispatchToProps(dispatch, ownProps)

  • диспетчеризация = store.dispatch() функция
  • ownProps = реквизит <MyOwnComponent />

И mapStateToProps, и mapDispatchToProps должны возвращать объект, который затем передается <MyOwnComponent /> в качестве реквизита. Этот пример взят из Документации Redux.

/* actions.js */
// This is an action creator
export function setVisibilityFilter(filter) {
  
  // returned value is action
  return { 
    type: SET_VISIBILITY_FILTER, 
    filter 
  }
}
/* FilterLink.js */
import { connect } from ‘react-redux’
import { setVisibilityFilter } from ‘../actions’
import Link from ‘../components/Link’
​
const mapStateToProps = (state, ownProps) => {
  return {
    active: ownProps.filter === state.visibilityFilter
  }
}
// In <Link /> one would call this.props.onClick() in order to send
// action (created by setVisibilityFilter() to store
const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    onClick: () => {
      dispatch(setVisibilityFilter(ownProps.filter))
    }
  }
}
// FilterLink is container component for Link
// ie. FilterLink connects Link to store​
const FilterLink = connect(
 mapStateToProps,
 mapDispatchToProps
)(Link)
​
export default FilterLink

Параметры по умолчанию для connect()

AddTodo = connect()(AddTodo) Это означает, что:

  • <AddTodo /> ничего не знает о государстве
  • <AddTodo /> может использовать функцию dispatch

Провайдер

Специальный компонент из библиотеки react-redux, который делает хранилище доступным для вызовов connect() в иерархии компонентов ниже. store передается в качестве реквизита <Provider store={store}>. Всегда должен быть на вершине иерархии компонентов.

Ресурсы

Я собрал некоторые ресурсы для своего репозитория на github: