Как обновить несколько свойств состояния с immer.js - PullRequest
0 голосов
/ 10 января 2019

Интересно, можно ли обновить несколько свойств состояния с помощью immer.js за один "вызов".

Скажите, у меня есть state:

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

И action creator:

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

Затем я использую action creator в компоненте React следующим образом:

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

Идея состоит в том, что я хочу обновить несколько свойств состояния одновременно. Но я не знаю, какие свойства это заранее. Я знаю, как это сделать с помощью простого редуктора:

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

Но how to update several properties of state with immer at the same time? Когда свойства состояния (которые следует обновить) заранее известны как .

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Вы можете переключаться на action.payload, как показано ниже:

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
    }
  }

Также: помните, что в последних версиях immer вполне допустимо возвращать объект, поэтому выполнение return Object.assign({}, state, action.payload) все еще действует в вызове produce.

0 голосов
/ 10 января 2019

Immer дает вам черновое состояние, которое вы можете редактировать. За кулисами он использует прокси-серверы ES6, чтобы узнать, что вы изменили, и неизменным образом применить ваши правки к исходному состоянию.

По сути, вы можете делать то же самое, что и сейчас, но используя API Immer:

import produce from 'immer'

const newState = produce(this.state, draft => Object.assign({}, draft, payload))

Если вы вместо этого знаете, какие свойства изменены, вы можете сделать что-то вроде:

const newState = produce(this.state, draft => {
  draft.propertyOne = 'newValue'
  draft.propertyTwo = 42
})
...