gpt4 book ai didi

reactjs - react useReducer 和上下文 : how to provide state selectors?

转载 作者:行者123 更新时间:2023-12-04 13:14:56 25 4
gpt4 key购买 nike

我在最初的问题中从来没有明确表达过,但我试图在没有 Redux 的情况下完成所有这些,这意味着没有 useSelector();

这是一个仅使用原生 React 来实现选择器的练习。


我正在尝试使用钩子(Hook)构建类似 Redux 的安排,我是 borrowing heavily from this guy

所以,我们有一个商店:

const CarStore = ({ children }) => {
const [state, dispatch] = useReducer(
carReducer,
[
{
type: 'fast',
mpg: 'bad',
},
],
);

return (
<CarStateContext.Provider value={selectors}>
<CarDispatchContext.Provider value={dispatch}>
{children}
</CarDispatchContext.Provider>
</CarStateContext.Provider>
);
};
export const CarStateContext = createContext();
export const CarDispatchContext = createContext();

现在,dispatch 可以通过 carReducer 自动访问 state,这非常好。即时还原!

好吧,无论如何,半个 Redux。我仍然缺少选择器,这是我的问题。考虑到上述上下文,我怎样才能最好地构建一个像 getCarType() 这样的选择器,它只会“快速”返回一个组件?

一个模糊的想法是这样的:

const CarStore = ({ children }) => {
const [state, dispatch] = useReducer(
carReducer,
[
{
type: 'fast',
mpg: 'bad',
},
],
);

// selectors, kind of.
const selectors = {
getType: () => { return state.type; },
getMpg: () => { return state.mpg; },
};

return (
<CarStateContext.Provider value={selectors}> // <- don't return state, return selectors
<CarDispatchContext.Provider value={dispatch}>
{children}
</CarDispatchContext.Provider>
</CarStateContext.Provider>
);
};
export const CarStateContext = createContext();
export const CarDispatchContext = createContext();

我想这确实有效,但可能有更好的解决方案?

最佳答案

这里最好的通用解决方案是提供一个简单的 API,称为 useSelector,由 redux 提供,它接受回调并使用当前状态调用它并返回结果。

const CarStore = ({ children }) => {
const [state, dispatch] = useReducer(
carReducer,
[
{
type: 'fast',
mpg: 'bad',
},
],
);


const useSelector = (callback) => {
return callback(state)
};

return (
<CarStateContext.Provider value={{useSelector}}> // <- don't return state, return selectors
<CarDispatchContext.Provider value={dispatch}>
{children}
</CarDispatchContext.Provider>
</CarStateContext.Provider>
);
};
export const CarStateContext = createContext();
export const CarDispatchContext = createContext();

一旦你这样做了,你就可以将它用于任何组件,比如

const Comp = () => {
const {useSelector} = useContext(CarStateContext);
const type = useSelector((state) => { return state.type; })
const mpg = useSelector((state) => { return state.mpg; })

}

EDIT- 方法 2: 在上述情况下,您需要单独使用 useContext 以及 useSelector 为避免这种情况,您可以实现也将选择器用作钩子(Hook)。此外,您不需要两个独立的调度和状态上下文,您可以只使用一个

const CarStore = ({ children }) => {
const [state, dispatch] = useReducer(
carReducer,
[
{
type: 'fast',
mpg: 'bad',
},
],
);


const getValue = (callback) => {
return callback(state)
};

return (
<CarStateContext.Provider value={{getValue, dispatch}}> // <- don't return state, return selectors
{children}
</CarStateContext.Provider>
);
};
export const CarStateContext = createContext();

export const useSelector = (callback) => {
const {getValue} = useContext(CarStateContext);
return getValue(callback)
}
// Similarly dispatch can be provided like below
export const useDispatch = () => {
const {dispatch} = useContext(CarStateContext);
return dispatch
}

并在你的组件中使用它

import { useSelector, useDispatch } from 'path/to/useSelector'
const Comp = () => {
const type = useSelector((state) => { return state.type; })
const mpg = useSelector((state) => { return state.mpg; })
const dispatch = useDispatch();
}

关于reactjs - react useReducer 和上下文 : how to provide state selectors?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61418181/

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