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