我在react-redux应用中设置动作和缩减器。我需要一个函数来更新状态中的属性并将对象添加到其列表中,如果可能的话,使用扩展语法。这是我到目前为止所做的:
const defaultState = {
genres: {}
}
export default function(state = defaultState, action) {
switch(action.type) {
case 'ADD_GENRE':
return {
...state,
genres[action.name]: action.list //new code here
}
default:
return state;
}
}
我需要动态访问genres属性,就像使用其属性名称的数组一样:
const getMusicFromGenre = (genre) => {
return state.genres[genre];
}
reducer应接受以下操作,然后相应地修改状态:
// action
{
type: 'ADD_GENRE,
name: 'Rock',
list: ['Bohemian Rhapsody', 'Stairway to Heaven', 'Hotel California']
}
// old state
{
genres: {
"Pop": ['Billie Jean', 'Uptown Funk, 'Hey Jude']
}
}
// new state
{
genres: {
"Pop": ['Billie Jean', 'Uptown Funk, 'Hey Jude'],
"Rock": ['Bohemian Rhapsody', 'Stairway to Heaven', 'Hotel California']
}
}
如果有必要,我愿意采用不同的方法。
答案 0 :(得分:3)
您已走上正轨,但需要分别处理每个级别的嵌套。这是我为http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html撰写的一个例子:
function updateVeryNestedField(state, action) {
return {
....state,
first : {
...state.first,
second : {
...state.first.second,
[action.someId] : {
...state.first.second[action.someId],
fourth : action.someValue
}
}
}
}
}
您可能还想阅读我在http://redux.js.org/docs/recipes/reducers/PrerequisiteConcepts.html#immutable-data-management和https://github.com/markerikson/react-redux-links/blob/master/immutable-data.md链接的一些有关不可变数据处理的文章。
答案 1 :(得分:2)
immutability-helper是一个非常有用的库,用于执行状态更新。在您的情况下,它将像这样使用,如果没有现有项目,将创建一个新数组,或者如果存在预先存在的项目,则使用操作列表连接现有项目:
import update from 'immutability-helper';
const defaultState = {
genres: {}
}
const createOrUpdateList = (prev, list) => {
if (!Array.isArray(prev)) {
return list;
}
return prev.concat(list);
// or return [...prev, ...list] if you prefer
}
export default function(state = defaultState, action) {
switch(action.type) {
case 'ADD_GENRE':
return update(state, {
genres: {
[action.name]: {
$apply: prev => createOrUpdate(prev, action.list)
}
}
});
default:
return state;
}
}