Параметризованный селектор / фабрика селекторов
Эта функция принимает параметры для генерации селектора, как мы можем себе представить, каждый раз, когда функция вызывается, генерируется новый селектор, см. Пример ниже:
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), будет более полезным!