如何在 React 中更新特定的 redux 状态片段
How to Update specific slice of redux state in React
我在使用 redux 和 react-redux 更新状态时似乎遇到了麻烦。当我更新单个状态切片时,所有其他状态都会被删除。我知道这个问题的答案很简单,但我想不通,也没有在网上找到其他任何东西。
澄清一下,这是我的减速器:
const initialState = {
selectedLevel: null,
selectedVenue: null,
selectedUnitNumber: null,
selectedUnitName: null,
selectedYear: null
}
export default (state = initialState, action) => {
console.log('reducer: ', action);
switch (action.type){
case 'CHOOSE_LEVEL':
return action.payload;
case 'CHOOSE_VENUE':
return action.payload;
case 'CHOOSE_UNIT':
return action.payload;
case 'SHOW_COURSES':
return action.payload;
}
return state;
}
还有我的联合减速器:
export default combineReducers({
workshopSelection: WorkshopSelectReducer
});
所以我的初始状态是这样的:
workshopSelection: {
selectedLevel: null,
selectedVenue: null,
selectedUnitNumber: null,
selectedUnitName: null,
selectedYear: null
}
但是当我使用我的动作创作者之一时,例如:
export function chooseVenue(venue){
return {
type: 'CHOOSE_VENUE',
payload: {
selectedVenue: venue
}
}
}
我最终得到这样的状态:
workshopSelection: {
selectedVenue: 'London',
}
此对象中不受此动作创建者影响的所有其余状态已被完全清除。相反,我只希望所有其他条目保持原样并保留其原始值 - 在本例中为 null
,或已分配给它们的任何其他值。
希望一切都有意义。
干杯!
你基本上是用另一个对象(你的有效载荷,它也是一个对象)替换一个对象(以前的状态)。
就标准 JS 而言,这相当于你的减速器所做的:
var action = {
type: 'CHOOSE_VENUE',
payload: {
selectedVenue: venue
}
};
var state = action.payload;
解决此问题的最简单方法是使用 Object spread properties:
export default (state = initialState, action) => {
switch (action.type){
case 'CHOOSE_LEVEL':
case 'CHOOSE_VENUE':
case 'CHOOSE_UNIT':
case 'SHOW_COURSES':
// Watch out, fall-through used here
return {
...state,
...action.payload
};
}
return state;
}
...但由于这仍处于试验阶段,您必须使用其他方式克隆以前的属性,然后覆盖新的属性。双 for ... in
循环可以是一个简单的循环:
export default (state = initialState, action) => {
switch (action.type){
case 'CHOOSE_LEVEL':
case 'CHOOSE_VENUE':
case 'CHOOSE_UNIT':
case 'SHOW_COURSES':
// Watch out, fall-through used here
const newState = {};
// Note: No key-checks in this example
for (let key in state) {
newState[key] = state[key];
}
for (let key in action.payload) {
newState[key] = action.payload[key];
}
return newState;
}
return state;
}
让您的有效负载对象在动作创建者上保持平坦,如下所示...
export function chooseVenue(venue){
return {
type: 'CHOOSE_VENUE',
selectedVenue: venue
}
}
并如下修改你的减速器(给出的例子是为了更新场地,对其他情况也做同样的事情......)
export default (state = initialState, action) => {
let newState = Object.assign({}, state); // Take copy of the old state
switch (action.type){
case 'CHOOSE_LEVEL':
case 'CHOOSE_VENUE':
newState.selectedVenue = action.selectedVenue; // mutate the newState with payload
break;
case 'CHOOSE_UNIT':
case 'SHOW_COURSES':
default :
return newState;
}
return newState; // Returns the newState;
}
我在使用 redux 和 react-redux 更新状态时似乎遇到了麻烦。当我更新单个状态切片时,所有其他状态都会被删除。我知道这个问题的答案很简单,但我想不通,也没有在网上找到其他任何东西。
澄清一下,这是我的减速器:
const initialState = {
selectedLevel: null,
selectedVenue: null,
selectedUnitNumber: null,
selectedUnitName: null,
selectedYear: null
}
export default (state = initialState, action) => {
console.log('reducer: ', action);
switch (action.type){
case 'CHOOSE_LEVEL':
return action.payload;
case 'CHOOSE_VENUE':
return action.payload;
case 'CHOOSE_UNIT':
return action.payload;
case 'SHOW_COURSES':
return action.payload;
}
return state;
}
还有我的联合减速器:
export default combineReducers({
workshopSelection: WorkshopSelectReducer
});
所以我的初始状态是这样的:
workshopSelection: {
selectedLevel: null,
selectedVenue: null,
selectedUnitNumber: null,
selectedUnitName: null,
selectedYear: null
}
但是当我使用我的动作创作者之一时,例如:
export function chooseVenue(venue){
return {
type: 'CHOOSE_VENUE',
payload: {
selectedVenue: venue
}
}
}
我最终得到这样的状态:
workshopSelection: {
selectedVenue: 'London',
}
此对象中不受此动作创建者影响的所有其余状态已被完全清除。相反,我只希望所有其他条目保持原样并保留其原始值 - 在本例中为 null
,或已分配给它们的任何其他值。
希望一切都有意义。
干杯!
你基本上是用另一个对象(你的有效载荷,它也是一个对象)替换一个对象(以前的状态)。
就标准 JS 而言,这相当于你的减速器所做的:
var action = {
type: 'CHOOSE_VENUE',
payload: {
selectedVenue: venue
}
};
var state = action.payload;
解决此问题的最简单方法是使用 Object spread properties:
export default (state = initialState, action) => {
switch (action.type){
case 'CHOOSE_LEVEL':
case 'CHOOSE_VENUE':
case 'CHOOSE_UNIT':
case 'SHOW_COURSES':
// Watch out, fall-through used here
return {
...state,
...action.payload
};
}
return state;
}
...但由于这仍处于试验阶段,您必须使用其他方式克隆以前的属性,然后覆盖新的属性。双 for ... in
循环可以是一个简单的循环:
export default (state = initialState, action) => {
switch (action.type){
case 'CHOOSE_LEVEL':
case 'CHOOSE_VENUE':
case 'CHOOSE_UNIT':
case 'SHOW_COURSES':
// Watch out, fall-through used here
const newState = {};
// Note: No key-checks in this example
for (let key in state) {
newState[key] = state[key];
}
for (let key in action.payload) {
newState[key] = action.payload[key];
}
return newState;
}
return state;
}
让您的有效负载对象在动作创建者上保持平坦,如下所示...
export function chooseVenue(venue){
return {
type: 'CHOOSE_VENUE',
selectedVenue: venue
}
}
并如下修改你的减速器(给出的例子是为了更新场地,对其他情况也做同样的事情......)
export default (state = initialState, action) => {
let newState = Object.assign({}, state); // Take copy of the old state
switch (action.type){
case 'CHOOSE_LEVEL':
case 'CHOOSE_VENUE':
newState.selectedVenue = action.selectedVenue; // mutate the newState with payload
break;
case 'CHOOSE_UNIT':
case 'SHOW_COURSES':
default :
return newState;
}
return newState; // Returns the newState;
}