更新嵌套的React Redux状态

时间:2019-03-16 13:47:24

标签: reactjs react-redux immer.js

初始化后,我使用react redux(带有immer)来存储我的应用程序的选项和样式。如何更改更新功能以更新应用程序的特定样式/选项,而不更改其他选项/样式?

// reducer.js

export const common = produce((draft, action) => {
  if (!draft) {
    return {
      settings: {},
    };
  }
  switch (action.type) {
    case STORE_WIDGET_SETTINGS:
        draft.settings = action.payload.settings;
        return;

    case UPDATE_WIDGET_SETTINGS:
      draft.settings = action.payload.settings;
      return;

    default:
      return;
  }
});

更新功能应仅更新选项/样式状态,而不更改当前的选项/样式。

示例: 更新前的设置:

    options: {
      selector: '#root'
    },
    styles: {
      mainContainer: {
        backgroundColor: 'black',
        color: 'white',
      }
    }

使用option:{selector: '#container'}调用更新功能。 设置应更改为:

options: {
  selector: '#container'
},
styles: {
  mainContainer: {
    backgroundColor: 'black',
    color: 'white',
  }
}

1 个答案:

答案 0 :(得分:1)

要手动执行此操作,您需要在现有值的基础上更新状态的每个分支。您可以通过传播现有值并包括新值来做到这一点。

draft.settings = {
  ...draft.settings, // Spread existing values
  ...action.payload.settings, // Override some values from action
  options: {
   ...draft.settings.options, // Spread existing values
   ...action.payload.settings.options // Override some values from action
  },
  styles: {
   ...draft.styles,
   ...action.payload.styles,
   mainContainer: {
   ...draft.styles.mainContainer,
   ...action.payload.mainContainer
   }
  }
}

您可以做一些简化的事情:

1)稍微弄平您的状态结构,以便没有太多的嵌套对象。这将使更新变得更容易,并且在将结构拉出数据(即选择器)时,您始终可以重新构建结构。诸如Normalizr之类的东西可以帮助您:https://github.com/paularmstrong/normalizr

2)分解更多的操作类型,以使并非每个更新都在单个UPDATE操作中发生。也许UPDATE_MAIN_CONTAINER等。

3)考虑使用类似Ramda的merge函数为您完成此操作:https://ramdajs.com/docs/#merge

此答案中的链接: