Используйте Parameterized Selector (фабрика селекторов) в функциональных компонентах React с помощью useSelector из React-Redux - PullRequest
0 голосов
/ 29 февраля 2020

Параметризованный селектор / фабрика селекторов

Эта функция принимает параметры для генерации селектора, как мы можем себе представить, каждый раз, когда функция вызывается, генерируется новый селектор, см. Пример ниже:

const makeGetSomeSelector = ({ param1, param2, ...}) =>
    createSelector(
       parentSelector,        // suppose it's declared before
       result =>  result.getIn([param1, param2, ...], defaultValue)
    )

Общий случай

Теперь мы хотим использовать его в функциональном компоненте React, и так как в реакторе-редуксе введено useSelector , и на основе предоставленного примера в компоненте это должно выглядеть так:

import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { makeGetSomeSelector } from 'XXX/selectors.js';

const MyComponent = ({ param1, param2, ... }) => {
    const getSomeSelector = useMemo(
       () => makeGetSomeSelector({param1, param2, ...}),
       [param1, param2, ...]
    );
    const selectorResult = useSelector(getSomeSelector);
    ...
}      

Случай, когда речь идет о константах

Пока что все имеет смысл. Однако есть случай, когда параметры не являются динамическими c (например, из реквизита, состояний и т. Д. c.), Вместо этого они являются константами! Тогда это становится:

import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { makeGetSomeSelector } from 'XXX/selectors.js';
import { const1, const2, ... } from 'XXX/constants.js';

const MyComponent = () => {
    const getSomeSelector = useMemo(
       () => makeGetSomeSelector({const1, const2, ...}),
       []          // note that here we don't have any dependencies.
    );
    const selectorResult = useSelector(getSomeSelector);
    ...
}      

Однако кто-то спросил меня, почему бы не использовать следующий способ:

import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { makeGetSomeSelector } from 'XXX/selectors.js';
import { const1, const2, ... } from 'XXX/constants.js';

const getSomeSelector = makeGetSomeSelector({const1, const2, ...});
// declare outside of component, since all params are just constants.

const MyComponent = () => {
    const selectorResult = useSelector(getSomeSelector);
    ...
}

Вопрос

Какой из них правильный, или оба в порядке?

Правильность означает, что результат (и, возможно, все промежуточные результаты) селектора действительно запомнен / кэширован и не приведет к такой проблеме, как новый селектор создан и потерян функция памятки ?

Если кто-нибудь мог бы рассказать о том, как фабрика селекторов работает с useSelector (помимо примера response-redux), будет более полезным!

...