Закончил на хекслете курс по редуксу. Эта библиотека предназначена для управления состоянием и сама по себе оказалась неожиданно простой. Покажу основные тезисы на примитивном примере.
Нужно сделать приложение, которое показывает счетчик и две кнопки, которые увеличивают и уменьшают значение счетчика. Вот такое: https://jsbin.com/jasidut/edit?html,output
Для описания состояния такого приложения достаточно одного числа, которое символизирует значение счетчика. Состояние хранится в специальном объекте под названием store
. Чтобы посмотреть, что в этом объекте находится, есть метод getState()
:
store.getState();
// 0
Чтобы поменять состояние существует единственный способ: передать в store
другой объект под названием action
.
Action
— это обыкновенный джаваскриптовский объект, который описывает изменение, которые мы хотим произвести над состоянием. В нем есть должно быть одно обязательное свойство type
и сколько угодно опциональных свойств с любыми данными.
Action
передается в store
при помощи метода dispatch()
. Например, чтобы увеличить значение счетчика, нужно передать action
с типом INCREMENT:
store.getState();
// 0
store.dispatch({ type: 'INCREMENT' });
store.getState();
// 1
То, как именно обновляется состояние в зависимости от переданного сообщения, определяется специальной функцией под названием reducer
, которая принимает два аргумента: state
и action
. От этой функции требуется, чтобы она правильно обновляла состояние в зависимости от переданного action
. В примере со счетчиком редьюсер будет выглядеть так:
const reducer = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
};
Эту функцию называют редьюсером из-за сходства со стандартной операцией над списком reduce
. В редьюс передают функцию, которая последовательно обновляет аккумулятор основываясь на элементах в списке. Так же и редьюсер после каждого задиспатченного экшена обновляет состояние.
Наконец, нужно создать хранилище на основе редьюсера:
import { createStore } from 'redux';
const store = createStore(reducer);
Последний метод у хранилища называется subscribe()
. Он принимает функцию, которая будет выполняться после каждого обновления состояния. Вот так, например, можно автоматически выводить состояние хранилища в консоль после каждого обновления:
store.subscribe(() => console.log(store.getState()));
На этом возможности редукса заканчиваются. Сложности начинаются, когда нужно подключить редукс к реакту и написать что-то посложнее счетчика. Для этого есть куча дополнительных библиотек, которые и рассматриваются в хекслетовском курсе: react-redux для интеграции с реактом, redux-form для работы с формами, redux-actions для того, чтобы не создавать экшены вручную, и так далее. В определенный момент начинаешь путаться в этом разнообразии, пытаясь держать в голове все эти разрозненные элементы.
Для особо любознательных рекомендую дополнительно серию видосов по редуксу, записанных его автором: https://egghead.io/courses/getting-started-with-redux. Там он между делом показывает, как написать собственную реализацию такой же библиотеки.