web-dev-qa-db-de.com

verhindern Sie, dass doppelte Objekte hinzugefügt werden, um die Redux-Reaktion zu aktivieren

Ich habe eine Frage zum Verhindern, dass Duplikate zu meinem Redux-Shop hinzugefügt werden.

Es sollte einfach sein, aber aus irgendeinem Grund funktioniert nichts, was ich versuche.

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;

    }

};

Die action sieht ungefähr so ​​aus:

{
   type: "ADD_EVENT",
   event: { event_id: 1, name: "Chelsea v Arsenal" }
}

Das Problem ist, dass die API, mit der ich arbeite, gelegentlich identische Nachrichten über einen Websocket sendet, was bedeutet, dass zwei identische Ereignisse zu meinem Shop hinzugefügt werden.

Ich habe viele Ansätze verfolgt, kann aber nicht herausfinden, wie dies funktioniert. Ich habe viele SO Antworten ausprobiert.

6
user7597670

Warum schlägt Ihr Code fehl?

Code:

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

Da Sie zuerst das neue Element hinzufügen und dann das selbe Element filtern, wird auf diese Weise niemals der neue Wert im Reduzierungsstatus hinzugefügt.


Lösung:

Verwenden Sie # array.findIndex , um zu überprüfen, ob das Element bereits im Array vorhanden ist oder nicht, und fügen Sie dann nur das Element hinzu, ansonsten wird derselbe Status zurückgegeben.

Schreiben Sie es so:

case "ADD_EVENT":

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

    if(index == -1)
        return [...state, action.event];
    return state;
3
Mayank Shukla

Lösung:

const eventReducer = ( state = [], action ) => {
    switch (action.type) {
        case 'ADD_EVENT':
            return state.some(( { event_id } ) => event_id === action.event.event_id)
                ? state
                : [...state, action.event];
        default:
            return state;
    }
};

Prüfung:

const state1 = eventReducer([], {
    type: 'ADD_EVENT',
    event: { event_id: 1, name: 'Chelsea v Arsenal' }
});

const state2 = eventReducer(state1, {
    type: 'ADD_EVENT',
    event: { event_id: 2, name: 'Chelsea v Manchester' }
});

const state3 = eventReducer(state2, {
    type: 'ADD_EVENT',
    event: { event_id: 1, name: 'Chelsea v Arsenal' }
});

console.log(state1, state2, state3);
1
Ivan Nikitovic

Sie können Array.prototype.find () verwenden.

Beispiel (nicht getestet)

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

Update (@ CodingIntrigues Kommentar)

Sie können für einen besseren Ansatz auch Array.prototype.some () verwenden

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;
    }
};
1
bennygenel

Sie können so etwas tun, damit der logische Teil sicherstellt, dass Sie nicht zweimal denselben Eintrag erhalten.

const x = filter.arrayOfData(item => item.event_id !== EVENT_FROM_SOCKET);
if (x.length === 0) {
  // dispatch action here
} else {
  // ignore and do nothing
}
0
Adeel Imran

Sie müssen vorsichtig sein, wenn Sie Arrays in Reduzierungen verwenden. Sie fügen der Liste im Wesentlichen weitere Elemente hinzu, wenn Sie anrufen:

[...state, action.event]

Wenn Sie stattdessen eine Karte verwenden, können Sie Duplikate vermeiden

const events = { ...state.events }
events[action.event.event_id] = action.event.name]
{...state, events }
0
Peter