在reducer redux中使用新内容更新数组

时间:2017-01-16 17:39:40

标签: javascript reactjs redux react-redux

我仍然关注函数式编程以及如何从reducer返回非变异对象。

我正在尝试替换reducer中旧对象的内容,而不会改变旧状态。

所以如果旧的状态是

 {
        Actors:"Michael Keaton, Jack Nicholson, Kim Basinger, Robert Wuhl"
        Awards:"Won 1 Oscar. Another 9 wins & 22 nominations."
        Country:"USA, UK"
        Director:"Tim Burton"
 }

并且新状态是

{
        Actors:"George Clooney"
        Awards:"Won 9 Oscars."
        Country:"USA"
        Director:"Quentin Tarantino"
 }

我的减速机看起来像这样

function reducer(state = {}, action){
  switch(action.type) {
    case 'GET_MOVIE':
      return //new Array here that has not been mutatated
    default:
        return state;
  }
}

我的有效负载看起来像这样

{
    Actors:"Michael Keaton, Jack Nicholson, Kim Basinger, Robert Wuhl"
    Awards:"Won 1 Oscar. Another 9 wins & 22 nominations."
    Country:"USA, UK"
    Director:"Tim Burton"
}

3 个答案:

答案 0 :(得分:1)

如果对象的所有值每次都在变化,您只需将新的有效负载作为新状态返回即可。但是,如果只有部分值发生变化,那么您可以使用ES6 Object.assignobject-assign作为npm模块。

如果所有值每次都在变化,

function reducer(state = {}, action){
   switch(action.type) {
    case 'GET_MOVIE':
      return action.payload;
    default:
        return state;
  }
}

如果某些值正在改变,那么

function reducer(state = {}, action){
   switch(action.type) {
    case 'GET_MOVIE':
      // let say Actors field changed, then 
      return Object.assign({}, state, {Actors: "Michael Keaton, Jack Nicholson, Kim Basinger, Robert Wuhl" });
    default:
        return state;
  }
}

答案 1 :(得分:0)

只需使用非变异函数并返回新的数据结构。

如果你的州只是{a:1,b:2,c:3},你希望它成为{a:4,b:5,c:6},只需返回{a:4,b:5 ,c:6}。

function reducer(state = {a: 1, b: 2, c: 3}, action){
  switch(action.type) {
    case 'GET_MOVIE':
      return action.payload // assuming action.payload = {a: 4, b: 5, c: 6}
    default:
        return state;
  }
}

当您想要新状态= [{a:1,b:2,c:3},{a:4,b:5,c:6}]时,它会变得更有趣。

有关mutative和non-mutative函数的良好列表,这很有用: https://jeff.is/blog/mutative-vs-non-mutative-array-methods-in-js.html

我还发现React的不变性助手很适合深度嵌套的结构。它们使用Mongo风格的语法。

答案 2 :(得分:0)

当你处理一个对象时,我对你为什么需要数组运算符感到有点困惑。使用此当前状态,您可以使用以下两种方法之一,具体取决于您的构建工具,polyfill和/或目标浏览器。

使用Object.assign()

function reducer(state = {}, action){
  switch(action.type) {
    case 'GET_MOVIE':
      return Object.assign({}, state, {
        Actors: action.Actors,
        Awards: action.Awards,
        Country: action.Country,
        Director: action.Director
      });
    default:
        return state;
  }
}

或使用点差运算符...

function reducer(state = {}, action){
  switch(action.type) {
    case 'GET_MOVIE':
      return {
        ...state,
        Actors: action.Actors,
        Awards: action.Awards,
        Country: action.Country,
        Director: action.Director
      }
    default:
        return state;
  }
}