Написание создателей операции вручную может быть утомительным. Redux Toolkit
предоставляет функцию createAction()
, которая генерирует создателя операции с указанным типом операции и преобразует переданные аргументы в поле payload
:
const addTodo = createAction('ADD_TODO');
addTodo({ text: 'Buy milk' });
// { type : "ADD_TODO", payload : {text : "Buy milk"}} )
createAction()
также принимает аргумент-колбек prepare
, позволяющий кастомизировать результирующее поле payload
и добавлять поле meta
, при необходимости.
Для определения того, как должно быть обновлено состояние, редукторы полагаются на тип операции. Обычно, это делается посредством раздельного определения типов и создателей операции. createAction()
позволяет упростить данный процесс.
Во-первых, createAction()
перезаписывает метод toString()
генерируемых создателей. Это означает, что создатель может использовать в качестве ссылки на “тип операции”, например, в ключах, передаваемых в builder.addCase()
или объектной нотации createReducer()
.
Во-вторых, тип операции также определяется как поле type
создателя.
const actionCreator = createAction('SOME_ACTION_TYPE');
console.log(actionCreator.toString());
// SOME_ACTION_TYPE
console.log(actionCreator.type);
// SOME_ACTION_TYPE
const reducer = createReducer({}, (builder) => {
// Здесь будет автоматически вызван `actionCreator.toString()`
// Кроме того, при использовании TypeScript, будет правильно предложен (предположен) тип операции
builder.addCase(actionCreator, (state, action) => {});
// Или вы можете указать поле `type`
// В этому случае, при использовании TypeScript, тип операции предложен не будет
builder.addCase(
actionCreator.type,
(state, action) => {}
);
});
Это означает, что нам не нужно создавать отдельную переменную для типа операции или дублировать название и значение типа, например: const SOME_ACTION_TYPE = 'SOME_ACTION_TYPE'
.
К сожалению, неявного приведения к строке не происходит в инструкции switch
. Приходится делать это вручную:
const actionCreator = createAction('SOME_ACTION_TYPE');
const reducer = (state = {}, action) => {
switch (action.type) {
// ошибка
case actionCreator: {
break;
}
// правильно
case actionCreator.toString(): {
break;
}
// так тоже работает
case actionCreator.type: {
break;
}
}
};
При использовании Redux Toolkit
с TypeScript
, принимайте во внимание, что компилятор TypeScript
может не осуществлять неявного преобразования в строку, когда создатель используется как ключ объекта. В этом случае также может потребоваться прямое указание типа создателя (actionCreator as string
) или использование поля type
в качестве ключа объекта.