我设置了以下选择器
选择器.js
const getNodeHistory = (state) => state.session.nodeHistory;
const getUnit = (state, unit) => unit;
export const selectNodeHistory = createSelector(
[getNodeHistory, getUnit],
(history, unit) => history.filter((h) => h.unit === unit)
);
控件
const nodeHistory = useSelector((state) => selectNodeHistory(state, unit));
然而,每一个使用selectNodeHistory的组件在state.session.nodeHistory发生变化时都会重新渲染,即添加或更改了一个新的项目,即使该项目不属于被过滤的选择器。
不知道是我做错了什么,还是使用这个方法不可能。
我将做一个选择器创建器,将库里的 unit
参数。我假设单位来自于道具,如果单位改变或历史改变,组件要重新计算。
const getNodeHistory = (state) => state.session.nodeHistory;
export const createSelectNodeHistory = (unit) =>// curry unit parameter
createSelector([getNodeHistory], (history) =>
history.filter((h) => h.unit === unit)
);
const Component = ({ unit }) => {
//memoize the selector (re create when unit changes)
// here memoization of unit parameter is done in component
// so each component has their own memoized selector
const selectNodeHistory = React.useMemo(
() => createSelectNodeHistory(unit),
[unit]
);
const nodeHistory = useSelector(selectNodeHistory);
};
在这个例子中,每个组件都会有自己的选择器。你也可以将备忘逻辑移到创建选择器的代码中,但是如果你使用这个选择器渲染多个具有不同单元值的组件,那么什么都不会被备忘,因为它们都共享同一个选择器。
//moved memoizing to create selector, memoization or unit is shared
// for all components calling createSelectNodeHistory
export const createSelectNodeHistory = createSelector(
(unit) => unit,
(unit) =>
createSelector([getNodeHistory], (history) =>
history.filter((h) => h.unit === unit)
)
);
const Component = ({ unit }) => {
//create memoized selector, will be re created when
// unit changes. Because memoization of unit is shared by
// all components nothing will be memoized when you do
// <Component unit={1} /><Component unit={2} />
const selectNodeHistory = createSelectNodeHistory(unit);
const nodeHistory = useSelector(selectNodeHistory);
};
现在来解决我们的问题;当nodeHistory发生变化,但该变化并没有影响history.filter时,你可以像这样将filter结果备忘化 本回答 在你的情况下,代码应该是这样的。
const createMemoizedArray = () => {
const memArray = defaultMemoize((...array) => array);
return (array) => memArray.apply(null, array);
};
export const createSelectNodeHistory = createSelector(
(unit) => unit,
(unit) => {
const memArray = createMemoizedArray();
return createSelector([getNodeHistory], (history) =>
memArray(history.filter((h) => h.unit === unit))
);
}
);
或者像这样,如果每个组件都需要自己的memomized选择器。
export const createSelectNodeHistory = (
unit // curry unit parameter
) => {
const memArray = createMemoizedArray();
return createSelector([getNodeHistory], (history) =>
memArray(history.filter((h) => h.unit === unit))
);
};