Reactjs 使用选择器钩子是更好地展开对象还是只指定所需的字段

Reactjs 使用选择器钩子是更好地展开对象还是只指定所需的字段,reactjs,react-redux,react-hooks,Reactjs,React Redux,React Hooks,如果我有一个巨大的对象,比如说40多个字段,我在一个组件中调用useSelector,但只需要该对象的3个字段,这样调用3个字段对性能是否更好: const user = useSelector((state) => ({ id: state.userReducer.id, name: state.userReducer.name, lastName: state.userReducer.lastName })); 在这种情况下,这是很好的,因为我们只需要3个

如果我有一个巨大的对象,比如说40多个字段,我在一个组件中调用useSelector,但只需要该对象的3个字段,这样调用3个字段对性能是否更好:

const user = useSelector((state) => ({
    id: state.userReducer.id,
    name: state.userReducer.name,
    lastName: state.userReducer.lastName
  }));
在这种情况下,这是很好的,因为我们只需要3个字段,但如果我们需要10个以上的字段,事情可能会变得相当详细。在这种情况下,扩展运算符为我节省了大量代码,但这是一种不好的做法吗?由于代码混淆、性能或其他原因

const user = useSelector((state) => ({ ...state.userReducer }));

出于性能原因,您应该这样做:

const user = useSelector(state => state.userReducer);
每当调度操作时,将运行选择器。如果它返回不同的内容,那么在最后一次运行时,它将强制组件重新渲染。通过扩展到一个新对象,它将始终返回一个新对象。因此,您的组件将在每个调度的操作上重新呈现

从:

useSelector还将订阅Redux应用商店,并运行 每当调度一个操作时,使用选择器

[……]

调度操作时,useSelector将执行引用 先前选择器结果值与当前选择器结果值的比较 结果值。如果它们不同,组件将被迫 重新渲染

[……]

默认情况下,useSelector使用strict==引用相等检查,而不是浅相等检查

我还发现关键的userReducer有点笨拙。它只是用户,而不是用户的减速器。reducer是一个纯粹的函数,它将操作转换为更改,而不是数据对象

编辑:

正如@Adam在评论中指出的,如果您想进一步减少重新渲染的数量,可以使用记忆选择器仅选择您感兴趣的状态。创建这样一个选择器的好库是

在您的情况下,只选择所需状态的最简单方法是告诉useSelector进行浅层相等比较,而不是引用相等比较。useSelector接受比较器函数作为第二个参数:

import { shallowEqual, useSelector } from 'react-redux'

const user = useSelector(
    ({user}) => ({
        id: user.id
        name: user.name
        lastName: user.lastName
    }),
    shallowEqual
);

最佳做法是仅从存储中获取渲染所需的少量数据,以限制重新渲染的数量。选择实际需要的更多数据的额外成本取决于所选数据的组件和更改频率。

出于性能原因,您应该这样做:

const user = useSelector(state => state.userReducer);
每当调度操作时,将运行选择器。如果它返回不同的内容,那么在最后一次运行时,它将强制组件重新渲染。通过扩展到一个新对象,它将始终返回一个新对象。因此,您的组件将在每个调度的操作上重新呈现

从:

useSelector还将订阅Redux应用商店,并运行 每当调度一个操作时,使用选择器

[……]

调度操作时,useSelector将执行引用 先前选择器结果值与当前选择器结果值的比较 结果值。如果它们不同,组件将被迫 重新渲染

[……]

默认情况下,useSelector使用strict==引用相等检查,而不是浅相等检查

我还发现关键的userReducer有点笨拙。它只是用户,而不是用户的减速器。reducer是一个纯粹的函数,它将操作转换为更改,而不是数据对象

编辑:

正如@Adam在评论中指出的,如果您想进一步减少重新渲染的数量,可以使用记忆选择器仅选择您感兴趣的状态。创建这样一个选择器的好库是

在您的情况下,只选择所需状态的最简单方法是告诉useSelector进行浅层相等比较,而不是引用相等比较。useSelector接受比较器函数作为第二个参数:

import { shallowEqual, useSelector } from 'react-redux'

const user = useSelector(
    ({user}) => ({
        id: user.id
        name: user.name
        lastName: user.lastName
    }),
    shallowEqual
);

最佳做法是仅从存储中获取渲染所需的少量数据,以限制重新渲染的数量。选择实际需要的更多数据的额外成本取决于所选数据的组成部分和更改频率。

我在“只获取您需要的数据”阵营。除了限制范围外,它还有一个额外的好处,即告诉您哪些键可用,而不必深入到reducer中。如果您选择全部选择,userReducer中的任何状态更改都将导致组件中的重新呈现。因此,非常重要的一点是,只要选择组件的必要状态,就可以满足您的需要。除了限制范围外,它还有一个额外的好处,即告诉您哪些键可用,而不必深入到reducer中。如果您选择全部选择,userReducer中的任何状态更改都将导致组件中的重新呈现。因此,只为组件选择必要的状态是非常重要的!此外,如果OP只需要用户减速器的某些部分,他们应该考虑使用一个不错的主意,将其包含在您的答案中!。编辑:考虑到这一点,你应该
一定要只带你需要的东西,带上你不需要的东西会导致不必要的重播。@Adam谢谢你的输入。把它加到我的答案里。是的!此外,如果OP只需要用户减速器的某些部分,他们应该考虑使用一个不错的主意,将其包含在您的答案中!。编辑:记住这一点,你绝对应该只带你需要的东西,带上你不需要的东西会导致不必要的重播。@Adam谢谢你的输入。把它加到我的答案里。