Wie füge ich dem Array im Reduzierer von React native redux ein Element hinzu?


140

Wie füge ich Elemente in mein Array arr[]des Redux-Status im Reduzierer ein? Ich mache das-

import {ADD_ITEM} from '../Actions/UserActions'
const initialUserState = {
    arr:[]
}

export default function userState(state = initialUserState, action)
{
    console.log(arr);
    switch (action.type)
    {
        case ADD_ITEM: 
            return { 
                      ...state,
                      arr: state.arr.push([action.newItem])
                   }

        default:
            return state
    }
}

Antworten:


361

Zwei verschiedene Optionen zum Hinzufügen eines Elements zu einem Array ohne Mutation

case ADD_ITEM :
    return { 
        ...state,
        arr: [...state.arr, action.newItem]
    }

ODER

case ADD_ITEM :
    return { 
        ...state,
        arr: state.arr.concat(action.newItem)
    }

1
Welches sollte als vorzuziehen angesehen werden?
Sapht

19
@sapht Wenn Sie Code in ES6 schreiben, bevorzugen Sie den ersten, der besser lesbar und eleganter ist.
Yadhu Kiran

5
Auch der erste ist rein, der zweite nicht. Aus den Redux-Dokumenten: "Es ist sehr wichtig, dass der Reduzierer rein bleibt. Dinge, die Sie niemals in einem Reduzierer tun sollten: 1. Mutieren Sie seine Argumente; 2. Führen Sie Nebenwirkungen wie API-Aufrufe und Routing-Übergänge aus; 3. Rufen Sie nicht reine Funktionen auf. zB Date.now () oder Math.random (). "
Charmanter Roboter

Hallo, @YadhuKiran, kannst du mir erklären, warum wir dem zweiten Index des Arrays einen neuen Wert hinzufügen, den ich nicht sehr gut verstehen konnte? arr: [...state.arr, why here?]
Oliver D

@OliverD, Wenn die Spread-Syntax wie oben verwendet wird, wird kein Element am zweiten Index, sondern am letzten Index eingefügt . Im Gegensatz dazu [action.newItem, ...state.arr]würde das Element an der ersten Position einfügen.
Yadhu Kiran

22

pushgibt nicht das Array zurück, sondern die Länge ( docs ). Sie ersetzen also das Array durch seine Länge und verlieren den einzigen Verweis darauf, den Sie hatten. Versuche dies:

import {ADD_ITEM} from '../Actions/UserActions'
const initialUserState = {

    arr:[]
}

export default function userState(state = initialUserState, action){
     console.log(arr);
     switch (action.type){
        case ADD_ITEM :
          return { 
             ...state,
             arr:[...state.arr, action.newItem]
        }

        default:return state
     }
}

1
Kann jemand diese Frage Object.assignfür die Änderungen des Arrays innerhalb des Status bitte beantworten ?
Vennesa

2
Warum brauchen Sie Object.assign? Es wird für Objekte verwendet und ist im Wesentlichen dasselbe. Wo Sie haben arr:[...state.arr, action.newItem], können Sie verwenden obj: Object.assign({}, state.obj, action.newItem, vorausgesetzt, dass objund newItemObjekte sind. Wenn Sie das dem ganzen Staat antun wollen, können Sie es einfach tunObject.assign({}, state, {arr: [..state.arr, action.newItem]})
martinarroyo

1
@martinarroyo, danke, dass ich es getan habe: var obj = { isLoading: true, data: ['a', 'b', 'c', 'd'] } var newObj = Object.assign({}, obj, { data: [...obj.data, 'e'] });und es gibt mir { isLoading: true, data: [ 'a', 'b', 'c', 'd', 'e' ] }Folgendes : für newObj, das gut genug für das ist, was ich brauche. Aber ich wollte Object.assign ohne den Spread-Operator verwenden, um das gleiche Ergebnis zu erzielen. Ist das möglich?
Vennesa

1
@Vennesa Ich denke, Sie können es durch ersetzen [].concat(obj.data, ['e']), wenn Sie keine ES6-Funktionen verwenden möchten. Object.assign ist für Objekte gedacht, und obwohl es keine Fehler bei der Verwendung in einem Array gibt, ist das Ergebnis keine Verkettung der Arrays. Wenn Sie es versuchen Object.assign({}, [1, 2, 3], [4]), erhalten Sie [4, 2, 3]als Ergebnis.
Martininarroyo

13

Wenn Sie an einer bestimmten Position im Array einfügen müssen, können Sie Folgendes tun:

case ADD_ITEM :
    return { 
        ...state,
        arr: [
            ...state.arr.slice(0, action.pos),
            action.newItem,
            ...state.arr.slice(action.pos),
        ],
    }

Ich bin hier gestolpert ... obwohl diese Antwort nicht genau zu der obigen Frage passt. Trotzdem war es genau das, wonach ich gesucht habe. Ich suchte nach einer Möglichkeit, ein Objekt in einen bestimmten Index in einem Array einzufügen. Daher habe ich die Antwort abgestimmt. Es war sehr hilfreich und sparte mir etwas Zeit. Vielen Dank!
Omostan

0

Ich habe eine Probe

import * as types from '../../helpers/ActionTypes';

var initialState = {
  changedValues: {}
};
const quickEdit = (state = initialState, action) => {

  switch (action.type) {

    case types.PRODUCT_QUICKEDIT:
      {
        const item = action.item;
        const changedValues = {
          ...state.changedValues,
          [item.id]: item,
        };

        return {
          ...state,
          loading: true,
          changedValues: changedValues,
        };
      }
    default:
      {
        return state;
      }
  }
};

export default quickEdit;

1
Fügen
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.