更新嵌套的 react redux 状态

Update nested react redux state

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

// 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/styles 状态而不改变当前 options/styles。

示例: 更新前的设置:

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

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

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

要手动执行此操作,您需要在现有值的基础上更新州的每个分支。您可以通过散布现有值并包括新值来实现。

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

此答案中的链接: