如何在Redux createSelector()上跨多个组件的记忆中断?



根据这里的文档:

创建唯一选择器实例:

在很多情况下,选择器函数需要跨多个组件重用。如果组件都将使用不同的参数调用选择器,它将破坏记忆——选择器在一行中不会多次看到相同的参数,因此永远不会返回缓存的值。

在我看来,这些陈述似乎是矛盾的。记忆会打破不同或相同的论点吗?为了理解这一点,我在这里创建了一个演示:

App.js:

import { useSelector, useDispatch } from "react-redux";
import { incrementX, incrementY, selectSum } from "./reducer";
function Sum({ value }) {
const state = useSelector((state) => state);
const sum = selectSum(state, value);
const dispatch = useDispatch();
return (
<div>
<span>
({state.x},{state.y})
</span>
<button onClick={() => dispatch(incrementX(1))}>X+1</button>
<button onClick={() => dispatch(incrementY(1))}>Y+1</button>
<br />
<span>sum: {sum}</span>
</div>
);
}
export default () => {
return (
<div>
<Sum value={1000} />
<Sum value={1000} />
</div>
);
};

reducer.js:

import { createSlice, createSelector } from "@reduxjs/toolkit";
const initialState = { x: 0, y: 0 };
const counterSlice = createSlice({
name: "data",
initialState,
reducers: {
// action creators to be auto-generated
incrementX(state, action) {
state.x += action.payload;
},
incrementY(state, action) {
state.y += action.payload;
}
}
});
export const { incrementX, incrementY } = counterSlice.actions;
export default counterSlice.reducer;
// input selectors
const selectX = (state) => state.x;
const selectY = (state) => state.y;
const selectSum = createSelector(
[selectX, selectY, (state, n) => n], // notation 1
(x, y, num) => {
console.log("output selector called: " + num);
return x + y + num;
}
);
export { selectSum };

当我单击任何按钮时,selectSum的输出选择器只记录一次,因此记忆是正确的。那么,为什么我们需要使用useMemo()或useCallback()呢?

标准情况是多个组件使用相同的选择器,并传入一些唯一的值。一个例子可能是某种"按类别"筛选的"项目"。组件:

function CategoryItemsList({category}) {
const filteredItems = useSelector(state => selectItemsForCategory( category));
// render here
}

现在假设应用程序有:

<CategoryItemsList category="a" />
<CategoryItemsList category="b" />

这两个组件每次都会用不同的第二个参数调用selectItemsForCategory("a"vs"b")。这意味着它永远不会正确地记忆,并且每次都必须重新计算结果

所以,有两种主要的方法来解决这个问题:
  • 为每个组件创建一个唯一的selectItemsForCategory实例,以便每个实例始终获得相同的参数
  • 在重选4.1中使用新的maxSize选项。X,它允许选择器有一个缓存大小>1

相关内容

  • 没有找到相关文章

最新更新