Во-первых, давайте определим некоторые действия.
Действия - это структура, которая передает данные из вашего приложения в хранилище. Они являются единственными источниками информации для хранилища. Вы отправляете их в хранилище используя метод store.dispatch()
.
Например, вот действие которое представляет добавление нового пункта в список дел:
{
type: 'ADD_TODO',
text: 'Build my first Redux app'
}
Действия - это обычные JavaScript объекты. Действия должны иметь поле type
, которое указывает на тип исполняемого действия. Типы должны, как правило, определяться как строковые константы. После того, как ваше приложение разрастется, вы можете захотеть переместить их в отдельный модуль.
import { ADD_TODO, REMOVE_TODO } from '../actionTypes';
Вам не нужно определять константы типа действий в отдельном файле или даже определить их и вовсе. Для небольшого проекта, было бы проще просто использовать строковые литералы для типов действий. Однако, есть некоторые преимущества в явном объявлении констант в больших проектах. Прочтите Reducing Boilerplate для знакомства с большим количеством практических советов, позволяющих хранить вашу кодовую базу в чистоте.
Кроме type
, структуру объекта действий вы можете строить на ваше усмотрение. Если вам интересно, изучите Flux Standard Action для рекомендаций о том, как могут строиться действия.
Мы добавим еще один тип действия, который будет отмечать задачу, как выполненную. Мы обращаемся к конкретному todo по index
, потому что мы храним их в виде массива. В реальном приложении, разумнее генерировать уникальный ID каждый раз, когда что-то новое создается.
{
type: COMPLETE_TODO,
index: 5
}
Это хорошая идея, передавать как можно меньше данных в каждом действии. Например, лучше отправить index
, чем весь объект todo.
Наконец, мы добавим еще один тип действия для редактирования видимых в данный момент задач.
{
type: SET_VISIBILITY_FILTER,
filter: SHOW_COMPLETED
}
Action creators - не что иное, как функции, которые создают действия. Довольно просто путать термины “action” and “action creator,” поэтому постарайтесь использовать правильный термин.
В традиционной реализации Flux, генераторы действий (action creators) при выполнении часто вызывают dispatch, примерно так:
function addTodoWithDispatch(text) {
const action = {
type: ADD_TODO,
text
};
dispatch(action);
}
В противоположность этому, в Redux генераторы действий (action creators) просто возвращают action:
function addTodo(text) {
return {
type: ADD_TODO,
text
};
}
Это делает их более переносимыми (portable ориг.) и легкими для тестирования. На самом деле, чтобы запустить отправку действия - передайте результат action creator в функцию dispatch()
:
dispatch(addTodo(text));
dispatch(completeTodo(index));
Или создайте связанный генератор действия (bound action creator) который автоматически запускает отправку действия:
const boundAddTodo = (text) => dispatch(addTodo(text))
const boundCompleteTodo = (index) => dispatch(completeTodo(index))
Теперь вы можете вызвать его напрямую:
boundAddTodo(text)
boundCompleteTodo(index)
Доступ к функции dispatch()
может быть получен непосредственно из хранилища (store) store.dispatch()
, но, что более вероятно, вы будете получать доступ к ней при помощи чего-то типа connect()
из react-redux. Вы можете использовать функцию bindActionCreators()
для автоматического привязывания большого количества генераторов действий (action creators) к функции dispatch()
.
/*
* типы действий
*/
export const ADD_TODO = 'ADD_TODO'
export const COMPLETE_TODO = 'COMPLETE_TODO'
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'
/*
* другие константы
*/
export const VisibilityFilters = {
SHOW_ALL: 'SHOW_ALL',
SHOW_COMPLETED: 'SHOW_COMPLETED',
SHOW_ACTIVE: 'SHOW_ACTIVE'
}
/*
* генераторы действий
*/
export function addTodo(text) {
return { type: ADD_TODO, text }
}
export function completeTodo(index) {
return { type: COMPLETE_TODO, index }
}
export function setVisibilityFilter(filter) {
return { type: SET_VISIBILITY_FILTER, filter }
}
Теперь давайте создадим несколько редьюсеров для того, чтобы описать как будет обновляться состояние (state) когда мы отправляем действия (actions)!
Если Вы уже знакомы с базовыми концептами и уже освоили этот обучающий материал, то не забудьте заценить асинхронные действия (async actions) в руководстве для опытных, чтобы научиться работать с AJAX ответами и создавать генераторы действий для асинхронного потока управления.