根据这里的文档:
创建唯一选择器实例:
在很多情况下,选择器函数需要跨多个组件重用。如果组件都将使用不同的参数调用选择器,它将破坏记忆——选择器在一行中不会多次看到相同的参数,因此永远不会返回缓存的值。
在我看来,这些陈述似乎是矛盾的。记忆会打破不同或相同的论点吗?为了理解这一点,我在这里创建了一个演示:
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