How do I add an element to array in reducer of React native redux?

React NativeReduxReact Redux

React Native Problem Overview


How do I add elements in my array arr[] of redux state in reducer? I am doing this-

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

React Native Solutions


Solution 1 - React Native

Two different options to add item to an array without mutation

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

OR

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

Solution 2 - React Native

push does not return the array, but the length of it (docs), so what you are doing is replacing the array with its length, losing the only reference to it that you had. Try this:

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

Solution 3 - React Native

If you need to insert into a specific position in the array, you can do this:

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

Solution 4 - React Native

Since this question gets a lot of exposure:

If you are looking for the answer to this question, there is a good chance that you are following a very outdated Redux tutorial.

The official recommendation (since 2019) is to use the official Redux Toolkit to write modern Redux code.

Among other things, that will eliminate string action constants and generate action creators for you.

It will also employ methods that allow you to just write mutating logic in your Reducers created by createReducer or createSlice, so there is no need to write immutable code in Reducers in modern Redux in the first place.

Please follow the official Redux tutorials instead of third-party tutorials to always get the most up-to-date information on good Redux practices and will also show you how to use Redux Toolkit in different common scenarios.

For comparison, in modern Redux this would look like

const userSlice = createSlice({
  name: "user",
  initialState: {
    arr:[]
  },
  reducers: {
    // no ACTION_TYPES, this will internally create a type "user/addItem" that you will never use by hand. You will only see it in the devTools
    addItem(state, action) {
      // you can use mutable logic in createSlice reducers
      state.arr.push(action.payload)
    }
  }
})

// autogenerated action creators
export const { addItem } = slice.actions;

// and export the final reducer
export default slice.reducer;

Solution 5 - React Native

If you want to combine two arrays, one after another then you can use

//initial state
const initialState = {
   array: [],
}

...
case ADD_ARRAY :
    return { 
        ...state,
        array: [...state.array, ...action.newArr],
    }
//if array = [1,2,3,4]
//and newArr = [5,6,7]
//then updated array will be -> [1,2,3,4,5,6,7]
...

This Spread operator (...) iterates array element and store inside the array [ ] or spreading element in the array, what you can simply do using "for loop" or with any other loop.

Solution 6 - React Native

I have a sample

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;

Solution 7 - React Native

The easiest solution to nested arrays is concat():

case ADD_ITEM: 
    state.array = state.array.concat(action.paylod)
    return state

concat() spits out an updated array without mutating the state. Simply set the array to the output of concat() and return the state.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questioncoderzzz18View Question on Stackoverflow
Solution 1 - React NativeyadhuView Answer on Stackoverflow
Solution 2 - React NativemartinarroyoView Answer on Stackoverflow
Solution 3 - React NativeJoeTideeView Answer on Stackoverflow
Solution 4 - React NativephryView Answer on Stackoverflow
Solution 5 - React NativeVishal PawarView Answer on Stackoverflow
Solution 6 - React NativeLong Nguyen QuiView Answer on Stackoverflow
Solution 7 - React NativeCristian View Answer on Stackoverflow