Search code examples
javascriptreactjsreduxreact-reduxredux-toolkit

How to destructure dynamically from action.payload in Redux Toolkit?


I go through the Redux Toolkit Docs to update mutable object values.

const errSignupSlice = createSlice({
  name: 'signupError',
  initialState: {
    firstName: "",
    lastName: "",
    emailID: "",
    password: "",
    confirmPassword: "",
    phoneNo: "",
  },
  reducers: {  
    addSignupError: (state, action) => {
            
      console.log('SLICES STARTED')
      console.log(action.payload)

      // action.payload = {
      //   emailID: 'Enter Minimum 6 character, Invalid Email Address',
      //   firstName: 'Enter Minimum 3 character',
      //   confirmPassword: 'confirm password do not match'
      // }

      // how can I de-structure dynamically
      const { emailID, firstName, confirmPassword } = action.payload
            
      return { ...state, emailID, firstName, confirmPassword }
    }
  }
)

The above code works as expected without any error, but I want to destructure dynamically, instead of manually destructuring the action.payload.

const { emailID, firstName, confirmPassword } = action.payload

Solution

  • You can use the Spread Syntax to expand, or "spread", the payload object properties into the new state object reference.

    const initialState = {
      firstName: "",
      lastName: "",
      emailID: "",
      password: "",
      confirmPassword: "",
      phoneNo: "",
    };
    
    const errSignupSlice = createSlice({
      name: 'signupError',
      initialState,
      reducers: {  
        addSignupError: (state, action) => {
          return {
            ...state,
            ...action.payload,
          };   
        },
      },
    );
    

    Some may say this hurts readability in terms of it not be clear what exactly will be the resultant state value since the entire payload is shallow copied, and by shallow copying you aren't really using a mutable update RTK allows. In many cases you will want to be explicit with the state update.

    Example:

    const initialState = {
      firstName: "",
      lastName: "",
      emailID: "",
      password: "",
      confirmPassword: "",
      phoneNo: "",
    };
    
    const errSignupSlice = createSlice({
      name: 'signupError',
      initialState,
      reducers: {  
        addSignupError: (state, action) => {
          const { emailID, firstName, confirmPassword } = action.payload;
          state.firstName = firstName;
          state.emailID = emailID;
          state.confirmPassword = confirmPassword;
        },
      },
    );