Skip to content

Instantly share code, notes, and snippets.

@YozhEzhi
Created September 4, 2020 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YozhEzhi/36a482919687123bed9de210f6333809 to your computer and use it in GitHub Desktop.
Save YozhEzhi/36a482919687123bed9de210f6333809 to your computer and use it in GitHub Desktop.

Redux-приложение это:

  • состояние (state) приложения в одном месте;
  • однонаправленный поток данных;

Все состояние вашего приложения сохранено в объекте внутри одного хранилища (store). Единственный способ изменить дерево состояния - это вызвать действие (action), объект описывающий то, что случилось. Чтобы указать, каким образом действия преобразовывают дерево состояния - нужно использовать чистые "редюсеры".

ACTIONS Действия - это структуры, которые передают данные из вашего приложения в хранилище. Они являются единственными источниками информации для хранилища. Действия отправляются в хранилище используя метод store.dispatch(). Лучшая практика - это передавать как можно меньше данных в каждом действии. Например, лучше отправить index объекта, чем весь объект.

// Единственный способ изменить внутреннее состояние - это вызвать действие // Действия могут быть сериализированы, залогированы или сохранены и далее // воспроизведены. Примеры: store.dispatch({ type: 'INCREMENT' }); store.dispatch({ type: 'ADD_ITEM', index: 5 });

Обычно тип действия, описывают как константу. Например: const GET_PHOTO_REQUEST = 'GET_PHOTO_REQUEST' const GET_PHOTO_SUCCESS = 'GET_PHOTO_SUCCESS'

Чтобы вызвать actions, мы должны написать функцию, которая в рамках Flux/Redux называется - ActionsCreator. Генераторы действий (action creators) просто возвращают action: function addTodo(text) { return { type: ADD_TODO, text } }

Синхронное действие (actions):

  • пользователь кликнул на кнопку
  • dispatch action {type: ТИП_ДЕЙСТВИЯ, payload: доп.данные}
  • интерфейс обновился

Асинхронное действие:

  • пользователь кликнул на кнопку
  • dispatch action {type: ТИП_ДЕЙСТВИЯ_ЗАПРОС}
  • запрос выполнился успешно
    • dispatch action {type: ТИП_ДЕЙСТВИЯ_УСПЕШНО, payload: доп.данные}
  • запрос выполнился неудачно
    • dispatch action {type: ТИП_ДЕЙСТВИЯ_НЕУДАЧНО, error: true, payload: доп.данные ошибки}

REDUCER Редюсер - это чистая функция, которая принимает предыдущее состояние и действие (state и action) и возвращает следующее состояние (новую версию предыдущего). Работа Reducer'а - среагировать на вызов Action и изменить состояние приложения. Формат состояния (state) зависит от вас: он может быть примитивом, массивом, объектом или даже структурой данных Immutable.js. Важно только одно: нельзя изменять объект состояния напрямую, вместо этого, стои возвращать новый объект, если состояние изменилось.

function counter(state = 0, action) { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 default: return state } }

Вот список того, чего никогда нельзя делать в редюсере:

  • Непосредственно изменять то, что пришло в аргументах функции;
  • Выполнять какие-либо сайд-эффекты: обращаться к API или осуществлять переход по роутам;
  • Вызывать не чистые функции, например Date.now() или Math.random().

Главный редьюсер можно разбить на несколько более мелких, и с помощью combineReducers из пакета redux собрать их воедино. Каждый мелкий редьюсер будет отвечать за некий срез состояния.

STORE Store, "объединяет" редьюсер (reducer) и действия (actions), а так же имеет несколько чрезвычайно полезных методов, например:

  • содержит состояние приложения (application state);
  • предоставляет доступ к состоянию с помощью getState();
  • предоставляет возможность обновления состояния с помощью dispatch(action);
  • регистрирует слушатели (listeners) c помощью subscribe(listener).

// Создаем хранилище. import { createStore } from 'redux'; import todoApp from './reducers'; let store = createStore(todoApp);

// Каждый раз при обновлении состояния - выводим его // Отметим, что subscribe() возвращает функцию для отмены регистрации слушателя let unsubscribe = store.subscribe(() => console.log(store.getState()); )

// Отправим несколько действий store.dispatch(addTodo('Learn about actions')); store.dispatch(addTodo('Learn about reducers')); store.dispatch(toggleTodo(0)); store.dispatch(toggleTodo(1));

// Прекратим слушать обновление состояния unsubscribe();

В отличии от Flux, в Redux только один объект Store.

ПОТОК ДАННЫХ (Data Flow) Жизненный цикл данных в любом Redux приложении включает в себя 4 шага:

  1. Вызов store.dispatch(action);
  2. Хранилище Redux вызывает функцию-редюсер, который ему передали. Хранилище передаст два аргумента при вызове редюсера: текущее дерево состояния (current state tree) и действие (action).
  3. Главный редюсер может комбинировать результат работы нескольких редюсеров в единственное дерево состояния приложения.
  4. Хранилище Redux сохраняет полное дерево состояния, которое возвращает главный редюсер. Это новое дерево является следующим состоянием приложения.

ИСПОЛЬЗОВАНИЕ С REACT Компоненты-контейнеры. Компоненты-контейнеры - это React-компоненты, задача которых общаться с Redux и связывать props и dispatch функции. Чтобы связать все компоненты-контейнеры с хранилищем нужно использовать , и передавать хранилище - только в Провайдер.

MIDDLEWARE Middleware принимают входные данные, добавляют что-то и передают данные дальше. Redux мидлвэры используют для логирования, сообщения об ошибках, общения с асинхронным API, роутинга и т.д.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment