【问题标题】:Best practice in manipulating redux state locally in React component在 React 组件中本地操作 redux 状态的最佳实践
【发布时间】:2021-04-08 17:54:23
【问题描述】:

我想知道在处理从我的 redux 存储馈送到我的组件的数据时,最佳实践是什么。如果我需要合并来自两个不同 reducer 的数据或需要进一步清理一些数据。

想象一下,我有一个来自我的 redux 状态的名称列表,如下所示:

names =  [{ id: 1, name: 'name1' },
           { id: 2, name: 'name2' },
           { id: 3, name: 'name3' },
           { id: 4, name: 'name4' },
           { id: 5, name: 'name5' },]

还有一个属性列表,这些属性也来自我的另一个州。

attributes =  [{ id: 1, atrib: 'atrib1' },
               { id: 2, atrib: 'atrib2' },
               { id: 3, atrib: 'atrib3' },
               { id: 4, atrib: 'atrib4' },
               { id: 5, atrib: 'atrib5' },]

如果我需要合并这两个并得到结果:

namesAndAttributes =  [{ id: 1, name: 'name1', atrib: 'atrib1' },
                       { id: 2, name: 'name2', atrib: 'atrib2' },
                       { id: 3, name: 'name3', atrib: 'atrib3' },
                       { id: 4, name: 'name4', atrib: 'atrib4' },
                       { id: 5, name : 'name5', atrib: 'atrib5' },]

想象一下它是一长串数据,所以我不想将这个合并操作硬编码到我的组件根目录中的一个变量中,使用 .map(),因此它不会在每次渲染时重新计算。

我应该创建另一个本地状态并使用带有[names, attributes]useEffect 挂钩作为依赖项吗?或者我应该在我的 reducer 状态下创建另一个字段并在我的 reducer 中操作这些数据?

如果这些数据在我的应用程序的许多地方都使用过,我很乐意向我的 reducer 添加另一个字段和操作类型,但如果此操作仅在我的应用程序的一个组件中是必需的?

这里有对还是错? 谢谢!

【问题讨论】:

标签: reactjs redux react-redux


【解决方案1】:

你可以使用与 Redux 非常相配的 reselect 库。 https://github.com/reduxjs/reselect

因此,我们的想法是创建取决于您想要的状态的选择器,在您的情况下为 namesattributes。只有当它们发生变化时,您才会获得新数据,并且该选择器才会执行。

在你的例子中,你会有这样的东西:

店名

names = [
  { id: 1, name: 'name1' },
  { id: 2, name: 'name2' },
  { id: 3, name: 'name3' },
  { id: 4, name: 'name4' },
  { id: 5, name: 'name5' },
];

商店中的属性

attributes = [
  { id: 1, atrib: 'atrib1' },
  { id: 2, atrib: 'atrib2' },
  { id: 3, atrib: 'atrib3' },
  { id: 4, atrib: 'atrib4' },
  { id: 5, atrib: 'atrib5' },
];

选择器

import { createSelector } from 'reselect';

const getNamesFromReducer1 = (state) => state.reducer1.names;
const getAttributesFromReducer2 = (state) => state.reducer2.attributes;

export const getNamesWithAttributes = createSelector(
  [getNamesFromReducer1, getAttributesFromReducer2],
  (names, attributes) => {
    return names.map((name) => {
      return {
        ...name,
        ...attributes.find((attribute) => attribute.id === name.id),
      };
    });
  }
);

以及该选择器的实现

const mapStateToProps = (state) => {
  return {
    namesWithAttributes: getNamesWithAttributes(state)
  }
}

【讨论】:

  • 哇!不知道存在这样一个有用的工具。感谢您的宝贵时间!
  • @OmarOmeiri 欢呼!它是一个很好的概念,称为“memoize”。它是一个不仅仅与 Redux 相关的概念,查一下,它是一种很好的思维方式。
【解决方案2】:

使用展开运算符:

const namesAndAttributes = [{...names[0],...attributes[0]}]

【讨论】:

  • 这只是一些虚拟数据示例,有时需要的操作要复杂得多。
猜你喜欢
  • 2017-08-15
  • 1970-01-01
  • 2016-04-29
  • 2016-06-05
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 2022-07-18
  • 2019-05-05
相关资源
最近更新 更多