我一直在读关于从我的reducer(React-redux)返回的规范化状态,我想我明白,如果我不传播(...)状态返回,我的React应用程序将无法识别状态更改已发生且我的UI将不会更新。
也就是说,如果我返回一些东西:
data: action.payload.data // where this is an array
而不是我在下面的内容
...action.payload.data
我的用户界面没有更新(没有调用render())。
假设这是正确的(我的测试似乎显示),那么我对如何返回错误条件感到困惑。我在下面所做的是返回isLoading并将isErrored作为属性来代替单个数组属性。
这感觉很难看。就像我使用我的回归意味着成功的一件事和错误的另一件事。
建议更好的方法吗?我错过了什么?
export function sessionAttendee(state = {}, action) {
switch (action.type) {
case SESSIONATTENDEE_LOAD: {
return Object.assign({}, state, {
isLoading: true,
hasErrored: false
});
}
case SESSIONATTENDEE_LOAD_SUCCESS: {
return Object.assign({}, state, {
...action.payload.data
});
}
case SESSIONATTENDEE_LOAD_FAIL: {
console.log("SESSIONATTENDEE_LOAD_FAIL");
return Object.assign({}, state, {
isLoading: false,
hasErrored: true,
errorMessage: action.error.message
});
}
答案 0 :(得分:1)
Object.assign
返回一个新对象。这将确保您不会改变以前的状态。 this GitHub issue中有很多充分理由说明为什么要避免改变你的状态。
关于你的陈述“这感觉很难看。就像我使用我的回报意味着成功的一件事和错误的另一件事”我会说你实际上并没有使用你的回报做多件事。它们总是返回该reducer的状态对象。 switch语句中的所有不同之处在于您正在更新该对象的属性。
FWIW,我注意到你正在Object.assign
范围内传播,这可能是不必要的。这是我如何重写你的减速器,这样对我来说更有意义......
const initialState = {
isLoading: false,
hasErrored: false,
errorMessage: null
data: [],
}
export function sessionAttendee(state = initialState, action) {
switch (action.type) {
case SESSIONATTENDEE_LOAD: {
return {
...state,
isLoading: true,
hasErrored: false
}
}
case SESSIONATTENDEE_LOAD_SUCCESS: {
return {
...state,
data: action.payload.data
}
}
case SESSIONATTENDEE_LOAD_FAIL: {
return {
...state,
isLoading: false,
hasErrored: true,
errorMessage: action.error.message
}
}
default:
return state;
}
}
initialState
因为这使得阅读时更容易理解。不是要求,但我发现它有帮助。Object.asssign
切换到使用ES6点差运算符。