gpt4 book ai didi

reactjs - 我可以在不知道 sliced reducer 路径的情况下编写选择器吗?

转载 作者:行者123 更新时间:2023-12-04 03:27:54 25 4
gpt4 key购买 nike

我之前已经有一些将 React 和 Redux 与 JavaScript 结合使用的经验,但我刚刚开始了一个使用 TypeScript 的项目。在阅读 redux-toolkit 的文档时,我发现了创建选择器以方便从状态树中获取所需数据的想法。

现在,根据官方文档,在切片中编写选择器的指南要求您已经知道商店将如何命名该切片。例如,来自 Create React App redux-typescript template :

export const selectCount = (state: RootState) => state.counter.value;

请注意 state.counter 中的 counter 仅命名为 in the root reducer file :

export const store = configureStore({
reducer: {
counter: counterReducer,
},
});

这对我来说似乎是一个非常糟糕的主意,因为如果我在根 reducer 中更改切片的名称,我将需要返回到切片本身并在那里更新这个新名称。此外,当我不需要状态的另一部分的任何东西时,获取所有 RootState 似乎有点矫枉过正。

那么,我可以写一个只看到当前切片状态的选择器,让 combineReducers 函数来处理它的地址吗?示例:

export const selectCount = (state: CounterState) => state.value;

如果不是,是否有更好的方法从状态中读取特定值而不需要知道存储的确切结构?

最佳答案

更新:我已经发布an npm package for this .

选择器函数被传递给 useSelector/mapStateToProps,它使用完整的(全局)状态数据调用您的选择器函数。这意味着,您的选择器函数需要处理实际的存储对象,而不仅仅是您的切片对象。

如果您在 combine reducer 中更改存储结构,显然您的存储数据签名也会更改。

但是如果您仍然想解决这个问题,您可以使用如下辅助函数为每个切片创建选择器函数:

// helper method for our helper createGlobalSelector
const getNestedObject = (obj, ...keys) => keys.reduce((acc, cur) => acc[cur], obj);

// example of getNestedObject
// getNestedObject({a: {b: 32}}, 'a', 'b')
console.log(getNestedObject({ a: { b: 32 } }, 'a', 'b')); // 32

// Util function to create selector functions for a slice
// accepts an object of selector functions, and key structure for that store slice
// returns modified selector functions, which will work with useSelector / mapStateWithprops
const createGlobalSelector = (selectorFuncsObj, ...sliceStructure) =>
Object.fromEntries(
Object.entries(selectorFuncsObj).map(([key, selectorFunc]) => [
key,
(state) => selectorFunc(getNestedObject(state, ...sliceStructure))
])
);

// example of createGlobalSelector
// store structure: { a: { b: { x: 55, y: 65, z: 75 } } }
// selectX: (state) => state.x
// selectY: (state) => state.y
// selectZ: (state) => state.z

const { selectX, selectY, selectZ } = createGlobalSelector(
{ selectX: (state) => state.x, selectY: (state) => state.y, selectZ: (state) => state.z },
'a', 'b'
);

const store = { a: { b: { x: 55, y: 65, z: 75 } } };

console.log(selectX(store)); // 55

console.log(selectY(store)); // 65

console.log(selectZ(store)); // 75

在上面的示例中,createGlobalSelector 创建了选择器函数,它将处理实际的存储结构,您无需担心。

现在,使用 createGlobalSelector 助手实现您的选择器

const selectorFuncObj = { selectCount : (state) => state.value }

const sliceStructure = 'counter'


// selector function which can be exported and used inside `useSelector` / `mapStateToProps`
export const { selectCount } = createGlobalSelector(selectorFuncObj, sliceStructure)

// store: {counter: {value: 5}}
const count = useSelector(selectCount) // 5

更新:在网上搜索后,人们是如何解决这个问题的,我找到了this article .文中提到的两种方式对于一层深的store结构来说是好的,但是对于多级嵌套来说就比较麻烦了。上面的 util 函数很好地处理了深度嵌套的存储结构,在我看来,它解决了这个问题。另外,检查 this SO answer .

关于reactjs - 我可以在不知道 sliced reducer 路径的情况下编写选择器吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67281557/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com