如何使用immer.js更新多个状态属性

时间:2019-01-10 09:49:33

标签: reactjs redux immer.js

我想知道是否可以在一个“呼叫”中使用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
  };
}

然后我像这样在React组件中使用该action creator

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

这个想法是我想同时更新几个状态属性。但是我不知道它是预先设置的。我知道如何使用简单的reducer来做到这一点:

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

但是how to update several properties of state with immer at the same time吗?当状态属性(应更新的状态属性)预先未知时。

3 个答案:

答案 0 :(得分:1)

您可以像下面这样在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仍然有效。

答案 1 :(得分:1)

使用ES6,您可以通过以下方式做到这一点:

flutter devices

在这种情况下,其工作方式与不使用Immer时相同。所有属性将被合并(浅合并)为状态。如果您需要替换状态,只需返回export const state = produce((draft, action) => { switch (type) { case UPDATE_SEARCH_PAGE: return {...draft, ...action.payload} } }, initialState)

答案 2 :(得分:0)

Immer为您提供了可以编辑的草稿状态。在后台,它使用ES6代理来发现您所做的更改,并以不变的方式将您的编辑应用于原始状态。

基本上,您可以执行与现在相同的操作,但是使用Immer api:

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