这个功能如何运作?
export const thingySelector = createSelector(
(state: RootState) => state.thingy.data,
(data) => data
);
BR 丹
我鼓励您阅读使用选择器导出数据文档,特别是使用重新选择写入记忆选择器部分,以完整了解这些选择器函数以及它们为何有用/强大。
createSelector
函数工作的基本要点是它需要 1 个或多个“输入选择器”函数,例如示例中的 (state: RootState) => state.thingy.data
以及单个“输出选择器”,它获取输入的返回值并计算输出值,例如data => /* compute some value from data */
。
当调用计算的选择器函数时,输入的结果会在内部存储,并且仅当这些输入值发生变化时,才会调用输出函数来重新计算导出的输出值。
文档中的示例
const state = { a: { first: 5 }, b: 10 } const selectA = state => state.a const selectB = state => state.b const selectA1 = createSelector([selectA], a => a.first) const selectResult = createSelector([selectA1, selectB], (a1, b) => { console.log('Output selector running') return a1 + b }) const result = selectResult(state) // Log: "Output selector running" console.log(result) // 15 const secondResult = selectResult(state) // No log output console.log(secondResult) // 15
请注意,我们第二次调用
时,“输出 选择器”没有执行。因为selectResult
和selectA1
与第一次通话相同,selectB
能够 返回第一次调用的记忆结果。selectResult
编写一个仅输出其输入的选择器函数实际上是不正确的。
// This selector does nothing useful
export const thingySelector = createSelector(
(state: RootState) => state.thingy.data,
(data) => data
);
但是,假设数据是一个对象,也许编写一个选择器函数来转换选定的状态或执行一些工作,例如将其转换为数组,这是一个有用的选择器。
示例
export const selectThingyKeys = createSelector(
(state: RootState) => state.thingy.data,
(data) => Object.keys(data)
);
export const selectThingyValues = createSelector(
(state: RootState) => state.thingy.data,
(data) => Object.values(data)
);
一个常见的策略是让选择器函数仅选择引用的 1 层深度,因此您的示例可以像下面这样分解。
export const selectThingy = (state: RootState) => state.thingy;
export const selectThingyData = createSelector(
selectThingy,
thingy => thingy.data
);
如果您需要从应用程序状态的两个不同区域计算派生状态:
export const selectThingy = (state: RootState) => state.thingy;
export const selectStuff = (state: RootState) => state.stuff;
export const selectHiddenStuff = createSelector(
[selectStuff],
stuff => stuff.hidden,
);
export const selectThingyData = createSelector(
selectThingy,
thingy => thingy.data
);
export const selectHiddenDataStuff = createSelector(
[selectThingy, selectHiddenStuff],
[thingy, hiddenStuff] => {
// ... compute & return hidden thingy stuff, etc
}
);
要选择派生的隐藏事物数据,UI 只需调用
selectHiddenDataStuff
选择器,它不需要关心实际的状态形状。
const data = useAppSelector(selectHiddenDataStuff);