Search code examples
reactjsreduxredux-toolkit

How do you update a nested json object in state with createSlice in reduxjs?


I'm using a sort of unsafe methodology to update state with createSlice. I want to update the state dynamically given key value pairs in a json object sent during the dispatch process. Right now I am looping through the [key, value] pairs and updating them one by one. It's not great. Is there a way to set the state based on a shallow copy like { ...state.user, action.payload }. For me, doing the copy of the state just straight up wouldn't work. Seems like I might be missing something on how to use this, but I haven't been able to find anything about this in the docs. Any Help would be appreciated?

import { createSlice } from '@reduxjs/toolkit'

export const userSlice = createSlice({
  name: 'user',
  initialState: {
    user: {},
  },
  reducers: {
    set_user: (state, action) => {
      // Redux Toolkit allows us to write mutating logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a draft state and produces a brand new
      // immutable state based off those changes
      state.user = action.payload
    },
    update_user: (state, action) => {
      console.log(action.payload)
      //eg {x: 'y', z: '1'}
      for (const [key, value] of Object.entries(action.payload)) {
        console.log(key)
        console.log(value)
        state.user[key] = value
      }
    },
})

Solution

  • There is a built-in helper javascript method Object.assign() that does the same as your code

    The Object.assign() static method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.

    update_user: (state, action) => {
       state.user = Object.assign(state.user, action.payload)
    }
    

    However you can return the whole updated user as action.payload so you don't need to do that