在React Native Redux

时间:2017-01-08 19:47:29

标签: merge react-native react-redux

我有一个像这样的初始状态:

export const INITIAL_STATE = Immutable({
  payload: []
})

当我发出请求操作时,它返回一个对象数组,如下所示:

[
  {id: 1, name: 'userA'},
  {id: 2, name: 'userB'},
  {id: 3, name: 'userC'}
]

因此,当我尝试刷新状态时,我将现有的有效负载与从服务器获取的新有效负载合并:

export const success = (state, { payload }) => {
  const newPayload = state.payload.concat(payload)

  return state.merge({ payload: newPayload })
}

这使我的新州最终成为这样:

[
  {id: 1, name: 'userA'},
  {id: 2, name: 'userB'},
  {id: 3, name: 'userC'},
  {id: 4, name: 'userD'},
  {id: 5, name: 'userE'},
  {id: 6, name: 'userF'}
]

所以,那部分有效,但是,如果我再次调用我的请求操作,状态就会填充重复的数据,如下所示:

[
  {id: 1, name: 'userA'},
  {id: 2, name: 'userB'},
  {id: 3, name: 'userC'},
  {id: 4, name: 'userD'},
  {id: 5, name: 'userE'},
  {id: 6, name: 'userF'},
  {id: 1, name: 'userA'}, // <== duplicated data
  {id: 2, name: 'userB'}, // <== duplicated data
  {id: 3, name: 'userC'}  // <== duplicated data
]

我需要的是,如果我调用请求操作,并从服务器返回相同的数据 - 在这种情况下ID为1,2和3 - 那么state.merge只是保留有效负载或更新如果是这样的话,那么他们会使用新的值,所以如果id为2的用户在服务器中将他的名字更新为newUserB,那么我的新状态将是:

[
  {id: 1, name: 'userA'},
  {id: 2, name: 'newUserB'},
  {id: 3, name: 'userC'},
  {id: 4, name: 'userD'},
  {id: 5, name: 'userE'},
  {id: 6, name: 'userF'}
]

而不是:

[
  {id: 1, name: 'userA'},
  {id: 2, name: 'userB'},
  {id: 3, name: 'userC'},
  {id: 4, name: 'userD'},
  {id: 5, name: 'userE'},
  {id: 6, name: 'userF'},
  {id: 1, name: 'userA'},
  {id: 2, name: 'newUserB'},
  {id: 3, name: 'userC'}
]

我尝试使用state.merge({ payload: newPayload }, {deep: true}),但它没有按照我期望的方式工作,我也尝试了state.merge({ payload })和相同。

任何人都知道如何做到这一点?

1 个答案:

答案 0 :(得分:2)

首先合并两个数组,然后只过滤唯一的项目。

export const success = (state, { payload }) => {       
   const newArr = state.payload.concat(payload)  
   const idPositions = newArr.map(el => el.id)
   const newPayload = newArr.filter((item, pos, arr) => {
                                return idPositions.indexOf(item.id) == pos;
                              })

   return state.merge({ payload: newPayload })
}