Redux Reducer:这是从初始状态切换布尔值的可接受方式吗?
Redux Reducer: Is this an acceptable way to toggle a Boolean from the initial state?
我有一组对象作为初始状态。该数组保存用户 question/response 数据。在 HTML 页面上有一个 material-ui 开关来控制问题是 public 还是私人的。我知道 redux 建议在 action 中保留逻辑而不是 reducer,但这是我想出的解决方案。 "toggleSwitch reducer" 是一个可接受的解决方案还是我创建了一个反模式?
请注意,我使用 'reducer helper' 而不是 'switch statement' 来减少样板代码。
先感谢您。我对 redux 很陌生。
// ACTION
export const toggleQuestion = (questionId) => {
return {
type: TOGGLE_QUESTION,
payload: {
questionId
}
}
}
//REDUCER
const initialState = [{
id: '1',
firstName: 'James',
lastName: 'Smith',
question: 'Ask a question here?',
response: 'This is an answer to the question',
public: true,
created: '2019-23-11T01:50:00+00:00',
modified: null
},
{
id: '2',
firstName: 'Taylor',
lastName: 'Johnson',
question: 'Ask another question here?',
response: 'Here is another answer to another question',
public: true,
created: '2019-23-11T01:50:00+00:00',
modified: null
}
];
const toggleSwitch = (state, payload) => {
return [
...state.map((item) => {
if (item.id === payload.questionId) {
return Object.assign(item, {
public: !item.public
})
}
return item
})
]
}
export default createReducer(initialState, {
[CREATE_QUESTION]: createQuestion,
[UPDATE_QUESTION]: updateQuestion,
[DELETE_QUESTION]: deleteQuestion,
[TOGGLE_QUESTION]: toggleQuestion
});
// HELPER TO CREATE THE REDUCER
export const createReducer = (initialState, fnMap) => {
return (state = initialState, {
type,
payload
}) => {
const handler = fnMap[type];
return handler ? handler(state, payload) : state
}
}
简单的答案是如果你连续做同样的事情10次,你会得到相同的结果吗?
Reducer 应该是纯净的,没有任何副作用,意味着相同的输入,每次都会产生相同的输出。
根据你的例子,在我看来,相同的动作,针对相同的状态应该产生相同的输出,所以我会说是的,我认为这没有任何问题。
但是,您可以将该逻辑提取到一种效果,即作为更新的一部分简单地指示状态新值应该是什么。
不清楚您使用的是什么框架,但 React 有 Saga 和 Thunks,并且 Angular 有 NgRX,它为您提供 'safe' 在 reducer 之外应用副作用的地方。
我经常使用 normalizr 来创建数据模式,就像数据库一样。然后我使用 selectors
从我的商店为我的组件做很多繁重的工作。这让我可以让我的 reducer 非常简单,只真正关心它们处理的 props 的变化。
我有一组对象作为初始状态。该数组保存用户 question/response 数据。在 HTML 页面上有一个 material-ui 开关来控制问题是 public 还是私人的。我知道 redux 建议在 action 中保留逻辑而不是 reducer,但这是我想出的解决方案。 "toggleSwitch reducer" 是一个可接受的解决方案还是我创建了一个反模式?
请注意,我使用 'reducer helper' 而不是 'switch statement' 来减少样板代码。 先感谢您。我对 redux 很陌生。
// ACTION
export const toggleQuestion = (questionId) => {
return {
type: TOGGLE_QUESTION,
payload: {
questionId
}
}
}
//REDUCER
const initialState = [{
id: '1',
firstName: 'James',
lastName: 'Smith',
question: 'Ask a question here?',
response: 'This is an answer to the question',
public: true,
created: '2019-23-11T01:50:00+00:00',
modified: null
},
{
id: '2',
firstName: 'Taylor',
lastName: 'Johnson',
question: 'Ask another question here?',
response: 'Here is another answer to another question',
public: true,
created: '2019-23-11T01:50:00+00:00',
modified: null
}
];
const toggleSwitch = (state, payload) => {
return [
...state.map((item) => {
if (item.id === payload.questionId) {
return Object.assign(item, {
public: !item.public
})
}
return item
})
]
}
export default createReducer(initialState, {
[CREATE_QUESTION]: createQuestion,
[UPDATE_QUESTION]: updateQuestion,
[DELETE_QUESTION]: deleteQuestion,
[TOGGLE_QUESTION]: toggleQuestion
});
// HELPER TO CREATE THE REDUCER
export const createReducer = (initialState, fnMap) => {
return (state = initialState, {
type,
payload
}) => {
const handler = fnMap[type];
return handler ? handler(state, payload) : state
}
}
简单的答案是如果你连续做同样的事情10次,你会得到相同的结果吗?
Reducer 应该是纯净的,没有任何副作用,意味着相同的输入,每次都会产生相同的输出。
根据你的例子,在我看来,相同的动作,针对相同的状态应该产生相同的输出,所以我会说是的,我认为这没有任何问题。
但是,您可以将该逻辑提取到一种效果,即作为更新的一部分简单地指示状态新值应该是什么。
不清楚您使用的是什么框架,但 React 有 Saga 和 Thunks,并且 Angular 有 NgRX,它为您提供 'safe' 在 reducer 之外应用副作用的地方。
我经常使用 normalizr 来创建数据模式,就像数据库一样。然后我使用 selectors
从我的商店为我的组件做很多繁重的工作。这让我可以让我的 reducer 非常简单,只真正关心它们处理的 props 的变化。