【问题标题】:Merge state with array of objects ignoring duplicates in React Native Redux在 React Native Redux 中将状态与忽略重复的对象数组合并
【发布时间】:2017-01-08 19:47:29
【问题描述】:

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

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 }) 和同样的方法。

有谁知道如何做到这一点?

【问题讨论】:

  • 快速提问,你使用的是 Redux 对,你能贴出你的 reducer 函数的代码吗?
  • 我正在使用 redux,是的

标签: merge react-native react-redux


【解决方案1】:

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

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 })
}

【讨论】:

  • 我认为它不起作用,我仍然收到重复的条目...我认为 arr.indexOf(item) 并没有真正从 {id: 1, name: 中找到现有 id 'x'}
  • 天哪!它有效!性能呢?假设这个有效载荷预计在不久的将来会有几千个项目
  • 抱歉,我还没有测试过它的性能,所以我不能对此发表评论。
猜你喜欢
  • 2021-06-17
  • 2019-11-19
  • 2018-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多