React:检查密钥是否唯一

时间:2018-04-21 01:00:15

标签: javascript reactjs

在反应中,我想知道是否有办法测试反应键是否是唯一的。我有一系列我正在展示的专辑,这些是从mongodb中提取出来的。设置数据库的方式,数据库可以包含重复的条目,是的,它必须是这种方式,不,我不是在寻找一种方法来删除数据库查询中的重复项。希望在做出反应。

当您向下滚动页面时,客户端一次加载来自数据库的20个结果,在您继续滚动时根据用户生成的查询获取接下来的20个结果。最终,您将遇到这些重复项,并且react会生成唯一的键警告,因为唯一键是ID字符串。

this.props.data.map( album => {
  album.cover = (album.images[0]) ? album.images[0].url : null

  return <Album data={album} key={album.sid} />
})

我想知道是否有办法测试已经渲染的反应键的album.sid属性,如果已经渲染了键,则不渲染组件并移动到下一个。

2 个答案:

答案 0 :(得分:2)

您可以在操作创建器(或者如果您不使用Redux时返回API调用的结果的位置),reducer或组件中过滤重复项,如果您仍希望将其保留在Redux中无论出于何种原因。

O(n)重复过滤算法将是:

const seen = new Set();
const uniqueData = data.filter(({ sid }) => {
  if (seen.has(sid)) {
    return false;
  }
  seen.add(sid);
  return true;
});

如果您决定在组件级别执行此操作,则可能需要考虑使用某些memoization library,以便仅在组件重新呈现时data已更改时才重新计算过滤

答案 1 :(得分:0)

从我关于redux的评论(已删除)中回答此评论:

  

但是reducer会如何针对传入的结果检查已经加载的结果?你能用模拟的例子发一个答案吗?

使用哈希表:

const DEFAULT_STATE = {
  byId: [],
  byHash: {}
}

export default function (state = DEFAULT_STATE, action) {
  switch (action.type) {
    case GET_ALBUM:
      return {
        ...state,
        byId: state.byId.includes(action.payload.id)
          ? [ ...state.byId ]
          : [ ...state.byId, action.payload.id ],
        byHash: {
          ...state.byHash,
          [action.payload.id]: action.payload
        }
      }

    default:
      return state
  }
}

你的组件:

this.props.albumIds.map( id => {
  let album = this.props.albums[id]
  album.cover = (album.images[0]) ? album.images[0].url : null

  return <Album data={album} key={album.sid} />
})

假设mapStateToProps喜欢:

{
   albumIds: state.albums.byId,
   albums: state.albums.byHash
}