首页 > 解决方案 > 这个 useReduxState hook 和 useSelector 在性能方面的区别?

问题描述

我写了一个 useReduxState 钩子,它看起来像这样:

import { useSelector } from 'react-redux';

const pick = (object, keys) =>
    keys.reduce(
        (obj, key) => (object && Object.prototype.hasOwnProperty.call(object, key) ? { ...obj, [key]: object[key] } : obj),
        {},
    );

export default (reducer, values) =>
    pick(
        useSelector((state) => state[reducer]),
        values,
    );

我用这个作为,

const Component = React.memo(() => {
    const { someStateFromReducerA, someMoreStateFromReducerA } = useReduxState('reducerA', ['someStateFromReducerA', 'someMoreStateFromReducerA']);
    const { someStateFromReducerB } = useReduxState('reducerB', ['someStateFromReducerB']);

    return (
        <div>
            {someStateFromReducerA}
            {someMoreStateFromReducerA}
            {someStateFromReducerB}
        </div>
    );
});

export default Component;

尽管这似乎是一种方便的方法,但我想知道这种方法与以下方法之间是否有区别:

const Component = React.memo(() => {
    const [
        someStateFromReducerA,
        someMoreStateFromReducerA
    ] = useSelector(
            ({ reducerA: { someStateFromReducerA, someMoreStateFromReducerA } }) =>
                [someStateFromReducerA, someMoreStateFromReducerA]
        );
    const someStateFromReducerB = useSelector(({ reducerB: { someStateFromReducerB } }) => someStateFromReducerB);

    return (
        <div>
            {someStateFromReducerA}
            {someMoreStateFromReducerA}
            {someStateFromReducerB}
        </div>
    );
});

export default Component;

是否有更多的重新渲染useReduxState?我计划在不同组件的许多不同模块中使用这个钩子,我想知道是否有其他影响,例如创建更多冗余引用来声明,导致重新渲染。

标签: javascriptreactjsreact-hooks

解决方案


你的钩子的性能要差得多。

  1. 它会更频繁地重新渲染。useSelector()如果值与前一个值相同,则优化为不重新渲染。在您的情况下,您调用useSelector()选择整个减速器,而不是仅仅挑选您需要的东西。每当减速器中的任何内容发生变化时,它都会重新渲染。

  2. 在每次渲染中挑选出键的开销很大。你可以用useMemo()钩子来解决这个问题,以减少在某些事情发生变化时的采摘,但是当它确实发生变化时它仍然需要进行一些采摘。

你使用的第二个例子useSelector()更糟。由于它每次都会创建一个新数组,因此会导致返回值不相等,并且会在每个操作上重新渲染。

我的建议:useSelector()在组件中多次使用钩子,每次都返回一个最小的数据单元。不要批量选择。


推荐阅读