我似乎无法理解如何有效地将redux状态下的所有单选按钮设置为false,然后将原始动作创建器设置为true。
现在我努力尝试使用Object.assign
复制状态对象,同时还提供了一种方法来更改item.type === 'radio'
到false
的实际对象。
我认为某些代码可能接近真实的方式。
const state = {
'some_id_1': {
type: 'radio',
id: 'some_id_1',
checked: true
},
'some_id_2': {
type: 'radio',
id: 'some_id_2',
checked: false
},
'some_id_3': {
type: 'checkbox',
id: 'some_id_3',
checked: false
}
};
const state = Object.assign({}, state, (item) => {
if(item.type === 'radio') {
console.log('reset='+item);
item.checked = false;
}
return item;
});
return state;
但当然这不起作用,因为Object.assign
不起作用。
当然我也可以遍历对象的键,即' radio_box_1_id',...并将item.type === 'radio'
的任何内容设置为false,或者甚至将这些更改的值带出到一个单独的状态对象并使用另一个Object.assign
参数替换它。但这些似乎是额外的处理时间,而不是我正在寻找的完美解决方案。
由于
编辑:我的目标是将我的州的项目设置为未检查状态,如果它们是收音机,但尽量不要更改其他项目。如果可能,我想有效地做到这一点。我之后可以将正确的电台设置为真。
答案 0 :(得分:1)
虽然您没有指定state
形状或reducer
代码,但这是一项常见操作。
如果我理解正确,你会有一系列项目(对象),每个项目都有type
和id
。
如果type
是radio
,那么您将拥有checked
属性。
如果这是正确的,您可以使用Array.prototype.map()
方法并在检查操作有效负载内的id
时有条件地返回一个新对象(使用object spread)。
这是一个小例子:
const state = [{
type: 'radio',
id: 1,
checked: true
}, {
type: 'radio',
id: 2,
checked: false
}, {
type: 'text',
id: 88,
value: 'hi there'
}, {
type: 'radio',
id: 43,
checked: false
}];
const action = {
id: 2
};
console.log('before the change', state);
const nextState = state.map((item) => {
if (item.type === 'radio') {
return {
...item,
checked: item.id === action.id
}
}
return item; // not a radio, go on.
});
console.log('after the change', nextState);
<强>更新强>
作为更新的后续内容,现在我们知道了状态的形状,在处理对象而不是数组时,可以使用Object.keys
迭代键并使用Array.prototype.reduce()创建新对象符合你的条件:
const state = {
'some_id_1': {
type: 'radio',
id: 'some_id_1',
checked: true
},
'some_id_2': {
type: 'radio',
id: 'some_id_2',
checked: false
},
'some_id_3': {
type: 'checkbox',
id: 'some_id_3',
checked: false
}
};
const action = {
id: 'some_id_2'
};
console.log('before the change', state);
const nextState = Object.keys(state).reduce((result,currentKey) => {
const currentItem = state[currentKey];
if (currentItem.type === 'radio') {
result[currentKey] = {
...currentItem,
checked: currentItem.id === action.id
}
} else{
result[currentKey] = currentItem // not a radio, go on.
}
return result;
},{});
console.log('after the change', nextState);
修改强>
作为Ulysse BN评论的后续行动:
我不得不downvote:你修改过的答案并没有完全克隆状态。 如果在你的代码之后我运行状态['some_id_3']。foo ='bar',nextState 也将被修改,因为它们共享相同的对象引用。
这是误导性的,如果你没有改变一个对象,那么就没有必要重新创建它。这不是突变。
这是redux
中的常见做法,您可以在Updating an Item in an Array