Search code examples
reactjsreduxreact-reduxredux-toolkitimmer.js

Unable to Update State ReduxToolkit


I have a array of objects kept in my state, I want to be able to edit one of the objects in the array and update the state.

However, I cannot seem to update anything with the state except push more items into it.

I am using @reduxjs/toolkit and the createSlice() method for my reducers.

Here is my slice, it has some logic to pull the initial state array from an API.

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { BACKEND_API } from "../../utilities/environment";
import fetchViaApi from "../../utilities/fetchViaApi";

export const getInitialDashboards = createAsyncThunk(
    'dashboard/getDashboards',
    async () => {
        const response = await fetchViaApi('/dashboards', {
            baseUrl: BACKEND_API,
            method: "GET"
        });

        const data = await response.json();
        return data;
    }
)

const initialState = [];

const dashboardsSlice = createSlice({
    name: 'dashboards',
    initialState,
    reducers: {
        setDashboards: (state,action) => {
            state = action.payload;
        },
        updateDashboard: (state,action) => {
            // state.push(action.payload);

            state = [...state.slice(0, 5)];
        },
        deleteDashboard: (state, action) => {
        },
    },
    extraReducers: builder => {
        builder.addCase(getInitialDashboards.fulfilled, (state, action) => {
            action.payload.forEach(element => {
                state.push(element);
            });
        })
    }
});

export const { setDashboards, updateDashboard, editDashboard, deleteDashboard } = dashboardsSlice.actions;

export default dashboardsSlice.reducer;

The commented out state.push(action.payload) works fine, but sometimes I don't want to add new object to the array, but edit existing ones.

My thought was to slice the existing element out and add the new version back to the array. But I cannot slice the state.

I am using Redux DevTools in Chrome and watching the state not change after calling updateDashboard, there were 10 elements after getDashboards is completed.

enter image description here


Solution

  • You had the right idea, but your reducers need to be returning the new state, not assigning it.. e.g.

    reducers: {
            setDashboards: (state,action) => {
                return action.payload;
            },
            updateDashboard: (state,action) => {
                return [...state.slice(0, 5)];
            },
            deleteDashboard: (state, action) => {
                return [];
            },
        },