Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update multiple state properties with immer.js

I wonder if it is possible to update multiple properties of state with immer.js in one "call".

Say I have state:

export const initialState = {
  isUserLogged: false,
  menuIsClosed: false,
  mobileMenuIsClosed: true,
  dataArray: ["dog","cat"],
};

And action creator:

export function updateSearchPage(data) {
  return {
    type: UPDATE_SEARCH_PAGE,
    payload: data
  };
}

I then use that action creator in React component like this:

  this.props.updateSearchPage({
    isUserLogged: true,
    menuIsClosed: true,
    dataArray: ["dog","cat","owl"]
  })

The idea is that I want to update several properties of state at the same time. But I dont know which properties it is in advance. I know how to do it with a simple reducer:

case UPDATE_SEARCH_PAGE:
  return Object.assign({}, state, action.payload)

But how to update several properties of state with immer at the same time? When the state properties (which one should update) are unknown in advance.

like image 948
user1665355 Avatar asked Jan 10 '19 09:01

user1665355


1 Answers

You can cycle on action.payload like the following:

const yourReducer = (state, action) =>
  produce(state, draft => {
    switch (action.type) {
      case UPDATE_SEARCH_PAGE:
        Object.entries(action.payload).forEach(([k, v]) => {
          draft[k] = v;
        })
        break;
    // ... other
    }
  }

Also: remember that on recent versions of immer is perfectly legit to returns an object, so doing return Object.assign({}, state, action.payload) is still valid inside a produce call.

like image 56
keul Avatar answered Sep 30 '22 20:09

keul