How to update a value of a nested object in a reducer?

无人久伴 提交于 2019-12-17 22:23:44

问题


I have built my state like so

const list = {
  categories: {
   Professional: {
    active: false,
    names: [
      {
        id: 1,
        name: "Golf",
        active: false
      },
      {
        id: 2,
        name: "Ultimate Frisbee",
        active: false
      }
  ] 
}}

In my action I have added an ID option so I would like to change the active status when the user clicks the option to do so

I am using Immutable JS though not married to it. I am wondering how I could target the id of the object and update its active status in a reducer? I am also open to feedback on how to better improve my state


回答1:


This is very common thing, and, actually, quite daunting. As far as I know, there is no really good and well-adopted solution in plain JS. Initially, Object.assign approach was used:

return Object.assign({}, state, {
  categories: Object.assign({}, state.categories, {
    Professional: Object.assign({}, state.Professional, {
      active: true
    })
  })
});

This is too straightforward and cumbersome, I admit it, but I have to say that we've built few big applications with this approaches, and except for number of characters it is not bad. Nowadays, the most popular approach is using Object spread:

return {
  ...state,
  categories: {
    ...state.categories,
    Professional: {
      ...state.categories.Professional,
      active: true
    }
  }
}

The second approach is much more cleaner, so if you use plain JS, then it seems as a good choice. In Immutable.js I have to admit it is easier, you just do the next

return state.updateIn(['categories', 'Professional'], x => x.set('active', true));

But it has it's own drawbacks and caveats, so it is better to think about it seriously before committing to it.

And your last question regarding improving the state – usually it is better not to have such deep nesting (separate your concerns, very often fields don't depend on each other – like active status can be separated to another object), but it is hard to say because of no knowledge of your domain. Also, it is considered as normal thing to normalize your data.




回答2:


The Redux docs section on Structuring Reducers covers this. In particular, see the section on Immutable Update Patterns. The examples given are for plain JS objects and arrays, but the same approach applies - map() over the list, return the existing item for everything you don't want to update, and return a new version for the one you do want to update.

Per the docs, also note that it's easier to update a specific item if your data is stored in a normalized structure, since you can look it up by ID directly. The "Structuring Reducers" section covers normalization as well.



来源:https://stackoverflow.com/questions/40096036/how-to-update-a-value-of-a-nested-object-in-a-reducer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!