Redux reducer 状态突变和恢复初始状态
Redux reducer state mutations and restoring initial state
恢复初始状态的最佳方法是什么?
对于此示例,假设我可以通过调度以下操作来编辑汽车:
dispatch(actions.editModel('Civic'));
dispatch(actions.editType({
make: 'Ford',
model: 'Focus'
}));
dispatch(actions.restoreInitialState());
我的减速器是这样的:
const initialState = {
id: '1',
vehicle: 'car',
type: {
make: 'Honda',
model: 'Accord'
},
license: 'abc'
}
export default createReducer({
[actions.editType]: (state, payload) => ({
...state,
type: payload // payload is an object
}),
[actions.editModel]: (state, payload) => ({
...state,
type: {
...state.type,
model: payload // payload is a string
}
}),
[actions.restoreInitialState]: (state) => ({
state: initialState // initial state has nested objects
})
}, initialState)
是否存在我改变我的状态或不正确地恢复我的初始状态的风险?
这可能有点矫枉过正,但我正在考虑像这样编辑我的减速器:
export default createReducer({
[actions.editType]: (state, payload) => ({
...state,
type: {
...payload // payload is an object
}
}),
[actions.editModel]: (state, payload) => ({
...state,
type: {
...state.type,
model: payload // payload is a string
}
}),
[actions.restoreInitialState]: (state) => ({
state: {
...initialState // initial state has nested objects
}
})
}, initialState)
通过负载传递对象与仅引用初始状态有区别吗? (加上我的初始状态包含嵌套对象)
您可以简单地这样做:
[actions.restoreInitialState]: () => initialState;
你提出了一个很好的问题。要回答这个问题,您需要考虑为什么避免在 React 中改变数据如此重要。在每次状态变化时——React 都会对更新后的虚拟 DOM 与旧虚拟 DOM 进行浅层比较。在这种浅层比较中——当它遇到 object 时——它只检查 object 的地址。所以 - 只要您有 parent 的新地址 - DOM 就会正确更新。
现在,每次你从 reducer return - 只要你 return 使用更新的状态 object - return {... state} 或具有不同地址的 object - 例如。 return initialState - 太完美了。您无需担心突变。即使您在状态中有嵌套的 object,也是如此。只要您更改 parent 的地址 - DOM 就会正确更新。所以请随意使用您在第一种情况下所做的代码。您不需要分散在嵌套的 object 上。您的负载无论如何都会有一个不同的地址。
唯一会厌倦的就是做这样的事情:
case [actions.editModel]:
const updatedState = state
updatedState.model = payload;
return updatedState;
在这种情况下,状态 object 通过引用传递给 updatedState - 这意味着它们将共享相同的地址。并且由于您正在 returning updatedState - 地址没有改变并且 DOM 不会更新 correctly/consistently.
恢复初始状态的最佳方法是什么? 对于此示例,假设我可以通过调度以下操作来编辑汽车:
dispatch(actions.editModel('Civic'));
dispatch(actions.editType({
make: 'Ford',
model: 'Focus'
}));
dispatch(actions.restoreInitialState());
我的减速器是这样的:
const initialState = {
id: '1',
vehicle: 'car',
type: {
make: 'Honda',
model: 'Accord'
},
license: 'abc'
}
export default createReducer({
[actions.editType]: (state, payload) => ({
...state,
type: payload // payload is an object
}),
[actions.editModel]: (state, payload) => ({
...state,
type: {
...state.type,
model: payload // payload is a string
}
}),
[actions.restoreInitialState]: (state) => ({
state: initialState // initial state has nested objects
})
}, initialState)
是否存在我改变我的状态或不正确地恢复我的初始状态的风险? 这可能有点矫枉过正,但我正在考虑像这样编辑我的减速器:
export default createReducer({
[actions.editType]: (state, payload) => ({
...state,
type: {
...payload // payload is an object
}
}),
[actions.editModel]: (state, payload) => ({
...state,
type: {
...state.type,
model: payload // payload is a string
}
}),
[actions.restoreInitialState]: (state) => ({
state: {
...initialState // initial state has nested objects
}
})
}, initialState)
通过负载传递对象与仅引用初始状态有区别吗? (加上我的初始状态包含嵌套对象)
您可以简单地这样做:
[actions.restoreInitialState]: () => initialState;
你提出了一个很好的问题。要回答这个问题,您需要考虑为什么避免在 React 中改变数据如此重要。在每次状态变化时——React 都会对更新后的虚拟 DOM 与旧虚拟 DOM 进行浅层比较。在这种浅层比较中——当它遇到 object 时——它只检查 object 的地址。所以 - 只要您有 parent 的新地址 - DOM 就会正确更新。
现在,每次你从 reducer return - 只要你 return 使用更新的状态 object - return {... state} 或具有不同地址的 object - 例如。 return initialState - 太完美了。您无需担心突变。即使您在状态中有嵌套的 object,也是如此。只要您更改 parent 的地址 - DOM 就会正确更新。所以请随意使用您在第一种情况下所做的代码。您不需要分散在嵌套的 object 上。您的负载无论如何都会有一个不同的地址。
唯一会厌倦的就是做这样的事情:
case [actions.editModel]:
const updatedState = state
updatedState.model = payload;
return updatedState;
在这种情况下,状态 object 通过引用传递给 updatedState - 这意味着它们将共享相同的地址。并且由于您正在 returning updatedState - 地址没有改变并且 DOM 不会更新 correctly/consistently.