Home > Software design >  How to add an object to an array using redux toolkit
How to add an object to an array using redux toolkit

Time:10-06

I want to add an object to an array reducer

This is the object am trying to add

 const id = 1;
 const type = 'deposit';

      dispatch(addTransaction({id, type}))

This is my reducer

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  transactions: [],
};

const transactionSlice = createSlice({
  name: 'transaction',
  initialState,
  reducers: {
    addTransaction: (state, action) => {
     state.transactions = [...state.transactions, action.payload];
},
  },
});

const { actions, reducer } = transactionSlice;

export const {
  addTransaction,
} = actions;

export default reducer;

Anytime I dispatch the object data, It updates the previous data, instead adding a new object in my transaction array.

CodePudding user response:

The problem is that you are not copying the transactions state before adding the new object to it. so do this instead:

reducers: {
    addTransaction: (state, action) => {
    state.transactions = [...state.transactions, action.payload];
    }

this way you copy all objects inside transactions array to a new array, plus the new object you want to add.

CodePudding user response:

try :

change

const initialState = {
  transactions: {
    items: [],
  },
};

to

const initialState = {
  transactions:[]
};

{ state.transactions: [...transactions, action.transaction] };

or keep initial state but change reducer to:

state.transactions.items = [...state.transactions.items, action.payload];

and according to redux toolkit docs there is no return in reducer

CodePudding user response:

Any of these two options should work:

Returning the updated state

const transactionSlice = createSlice({
  name: 'transaction',
  initialState,
  reducers: {
    addTransaction: (state, action) => {
     return [...state.transactions, action.payload];
    },
  },
});

Or for future scalability, make your initial state to be an object and add a key for your transactions, in this case items

const initialState = {
  transactions: {
    items: [],
  },
};

const transactionSlice = createSlice({
  name: 'transaction',
  initialState,
  reducers: {
    addTransaction: (state, action) => {
     transactions.items = [...state.transactions.items, action.payload];
   },
  },
});

With this object approach you can take advantage of Immer and get rid of having to spread the state just pushing the incoming payload

const transactionSlice = createSlice({
  name: 'transaction',
  initialState,
  reducers: {
    addTransaction: (state, action) => {
     transactions.items.push(action.payload);
    },
  },
});
  • Related