防止重复对象被添加到状态react redux

6 javascript ecmascript-6 reactjs redux react-redux

我有一个关于防止将重复项添加到我的redux商店的问题.

它应该是直截了当的,但出于某种原因,我尝试的任何工作都没有.

export const eventReducer = (state = [], action) => {

    switch(action.type) {

        case "ADD_EVENT":

            return [...state, action.event].filter(ev => {
                if(ev.event_id !== action.event.event_id){
                   return ev;
                }
            });


        default:
            return state;

    }

};
Run Code Online (Sandbox Code Playgroud)

action看起来像下面:

{
   type: "ADD_EVENT",
   event: { event_id: 1, name: "Chelsea v Arsenal" }
}
Run Code Online (Sandbox Code Playgroud)

问题在于,我正在使用的API通过websocket发送相同的消息,这意味着两个相同的事件被添加到我的商店.

我采取了很多方法,但无法弄清楚如何让它发挥作用.我尝试了很多SO答案,

ben*_*nel 5

您可以使用Array.prototype.find()

示例 (未测试)

const eventExists = (events, event) => {
  return evets.find((e) => e.event_id === event.event_id);
}
export const eventReducer = (state = [], action) = > {
    switch (action.type) {
    case "ADD_EVENT":
      if (eventExists(state, action.event)) {
        return state;
      } else {
        return [...state, action.event];
      }
    default:
        return state;
    }
};
Run Code Online (Sandbox Code Playgroud)

更新 (@CodingIntrigue 的评论)

您还可以使用Array.prototype.some()以获得更好的方法

const eventExists = (events, event) => {
  return evets.some((e) => e.event_id === event.event_id);
}
export const eventReducer = (state = [], action) = > {
    switch (action.type) {
    case "ADD_EVENT":
      if (eventExists(state, action.event)) {
        return state;
      } else {
        return [...state, action.event];
      }
    default:
        return state;
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 这是我要采取的方法。除了我用 [some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) 替换 `find` (3认同)

May*_*kla 5

为什么你的代码失败了?

代码:

return [...state, action.event].filter(ev => {
    if(ev.event_id !== action.event.event_id){
       return ev;
    }
});
Run Code Online (Sandbox Code Playgroud)

因为首先添加新元素然后过滤相同的元素,这样它永远不会在减速器状态中添加新值。


解决方案:

使用#array.findIndex来检查数组中是否已经存在项目,如果不存在则只添加元素,否则返回相同的状态。

像这样写:

case "ADD_EVENT":

    let index = state.findIndex(el => el.event_id == action.event.event_id);

    if(index == -1)
        return [...state, action.event];
    return state;
Run Code Online (Sandbox Code Playgroud)