Bagaimana cara menambahkan elemen ke array di reducer React native redux?

140

Bagaimana cara saya menambahkan elemen dalam susunan arr[]redux state di reducer? Saya melakukan ini-

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
    }
}
coderzzz18
sumber

Jawaban:

363

Dua opsi berbeda untuk menambahkan item ke array tanpa mutasi

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

ATAU

case ADD_ITEM :
    return { 
        ...state,
        arr: state.arr.concat(action.newItem)
    }
Yadhu Kiran
sumber
1
Mana yang harus dianggap lebih disukai?
sapht
19
@ sapht jika Anda menulis kode dalam ES6 yang lebih suka yang pertama yang lebih mudah dibaca dan elegan
Yadhu Kiran
5
Juga, yang pertama murni, yang kedua tidak. Dari dokumen Redux: "Sangat penting bahwa peredam tetap murni. Hal yang tidak boleh Anda lakukan di dalam peredam: 1. Mutasikan argumennya; 2. Lakukan efek samping seperti panggilan API dan transisi perutean; 3. Panggil fungsi non-murni, misalnya Date.now () atau Math.random (). "
Robot Memesona
Halo, @ YadhuKiran dapatkah Anda menjelaskan kepada saya mengapa kami menambahkan nilai baru dalam indeks kedua array yang tidak dapat saya pahami dengan baik? arr: [...state.arr, why here?]
Oliver D
@ OliverD, Ketika menyebar sintaks digunakan seperti di atas, itu tidak memasukkan elemen pada indeks kedua, tetapi pada indeks terakhir. Berbeda dengan ini, [action.newItem, ...state.arr]akan memasukkan elemen di posisi pertama.
Yadhu Kiran
22

pushtidak mengembalikan array, tetapi panjangnya ( docs ), jadi apa yang Anda lakukan adalah mengganti array dengan panjangnya, kehilangan satu-satunya referensi untuk itu yang Anda miliki. Coba ini:

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
     }
}
martinarroyo
sumber
1
Adakah yang bisa menjawab pertanyaan ini dengan Object.assignuntuk perubahan array di dalam negara tolong?
Vennesa
2
Mengapa Anda perlu Object.assign? Ini digunakan untuk objek, dan pada dasarnya hal yang sama. Di mana Anda memiliki arr:[...state.arr, action.newItem]Anda dapat menggunakan obj: Object.assign({}, state.obj, action.newItem, asalkan itu objdan newItembenda. Jika Anda ingin melakukan itu ke seluruh negara bagian, Anda bisa melakukannyaObject.assign({}, state, {arr: [..state.arr, action.newItem]})
martinarroyo
1
@martinarroyo, terima kasih sudah saya lakukan: var obj = { isLoading: true, data: ['a', 'b', 'c', 'd'] } var newObj = Object.assign({}, obj, { data: [...obj.data, 'e'] });dan ini memberi saya ini: { isLoading: true, data: [ 'a', 'b', 'c', 'd', 'e' ] }untuk newObj yang cukup baik untuk apa yang saya butuhkan. Tapi saya ingin menggunakan Object.assign tanpa operator spread untuk menghasilkan hasil yang sama. Apakah itu mungkin?
Vennesa
1
@ Vennesa Saya kira Anda bisa menggantinya dengan [].concat(obj.data, ['e']), jika Anda tidak ingin menggunakan fitur ES6. Object.assign dimaksudkan untuk objek, dan meskipun itu tidak akan memberi Anda kesalahan untuk menggunakannya pada array, hasilnya bukan gabungan dari array. Jika Anda mencoba Object.assign({}, [1, 2, 3], [4]), Anda mendapatkan [4, 2, 3]hasilnya.
martinarroyo
13

Jika Anda perlu memasukkan ke posisi tertentu dalam array, Anda dapat melakukan ini:

case ADD_ITEM :
    return { 
        ...state,
        arr: [
            ...state.arr.slice(0, action.pos),
            action.newItem,
            ...state.arr.slice(action.pos),
        ],
    }
JoeTidee
sumber
Saya tersandung di sini ... meskipun jawaban ini tidak persis cocok dengan pertanyaan di atas. Namun demikian, itulah tepatnya yang saya cari. Saya sedang mencari cara untuk memasukkan objek dalam indeks spesifik dalam array. Karena itu, saya memilih jawabannya. Itu sangat membantu dan menghemat waktu saya. Terima kasih!
omostan
0

Saya punya sampel

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;
Long Nguyen Qui
sumber
1
tambahkan beberapa deskripsi
SPatel