Тип действия, экспортируемый библиотекой redux-actions, нельзя использовать повторно
Обычно мы будем делать следующее, чтобы определить набор redux action&reducer с библиотекой redux-actions
export const {
open,
close,
send
} = createActions({
OPEN: payload => ({
payload
}),
CLOSE: payload => ({
payload
}),
SEND: payload => ({
payload,
})
});
export const combinedReducer = createActions({
[open]: (state, action) => { /*you do someting*/ },
[close]: (state, action) => { /*you do someting*/ },
[send]: (state, action) => { /*you do someting*/ }
});
/*in some where , we are going to handle the a triggered action type respectively in a switch statement.
but we have to use string concatenation to make the switch express strict equal pass , any graceful solution ? */
switch (action.type) {
case open + "":
//do someting
break;
case close + "":
//do someting
break;
case send + "":
//do someting
break;
}
Переменные open, close, send, сгенерированные выше, на самом деле являются типами функций, и их toString() переопределяются библиотекой redux-action для экспорта таких строк, как "OPEN", "CLOSE", "send"
однако, если мы хотим повторно использовать эти типы действий в операторе switch, мы должны объединить их с '' таким неуклюжим способом, чтобы просто передать выражение switch.
Есть ли какие-нибудь изящные способы избежать такого глупого кода при работе с синтаксическим анализом оператора switch, который обеспечивает строгое сравнение ===
заранее спасибо.
2 ответа
Возможно, я неправильно понял ваш вопрос, поэтому мой предыдущий ответ может не приблизиться к тому, что вы хотите.
Еще одна техника, которую я использовал, используя оба createActions()
а также switch/case
выглядело так:
import { createAction } from 'redux-actions'
// your action creators
export const myAction = createAction('ACTION_TYPE')
// your store slice/reducers
const defaultSliceState = {}
export const slice = (state = defaultSliceState, action) => {
switch(action.type) {
case myAction().type:
return Object.assign({}, state, { someValue: action.payload })
}
}
ОБНОВИТЬ
Если вам нужно обеспечить строгое равенство и вы не беспокоитесь о соблюдении типичных / симпатичных / аккуратных шаблонов, вы можете использовать это:
// your store slice/reducers
const ACTION_TYPE_1 = 'ACTION_TYPE_1'
const ACTION_TYPE_2 = 'ACTION_TYPE_2'
// add your action creators here: const myAction = createAction(ACTION_TYPE)
// ...
const defaultSliceState = {}
export const slice = (state = defaultSliceState, action) => {
switch(true) {
case action.type === ACTION_TYPE_1:
return Object.assign({}, state, { someValue: action.payload })
case action.type === ACTION_TYPE_2:
return Object.assign({}, state, { otherValue: doSomething(action.payload) })
}
}
... но вам даже не нужно делать это, если ваша ЕДИНСТВЕННАЯ забота - строгое равенство. Путем небольшого эксперимента я нашел switch/case
уже использует строгие проверки на равенство.
function match (arg) {
switch(arg) {
case 1: return "matched num"
case '1': return "matched str"
}
}
match(1) // -> matched num
match('1') // -> matched str
Один из способов использует handleAction
или же handleActions
функции, также обеспечиваемые примитивными действиями. Вместо того, чтобы написать длинный switch
заявление с [action.type]
В некоторых случаях вы вместо этого сопоставляете своих создателей действий с редукторами, использующими эти функции.
Это похоже на то, как мне нравится это делать:
import { createAction, handleActions } from 'redux-actions'
// your action creators
export const myAction = createAction('ACTION_TYPE`)
// your reducer (this example doesn't do anything useful)
const myReducer = (state, action) => Object.assign({}, state, { someValue: action.payload })
const sliceDefaultValue = {}
export const slice = handleActions({
[myAction]: myReducer
}, sliceDefaultValue)
handleAction
Документация по функциям находится здесь: https://redux-actions.js.org/api/handleaction.