gpt4 book ai didi

reactjs - 从 React 组件外部的 useReducer 检索当前状态

转载 作者:行者123 更新时间:2023-12-03 13:53:30 25 4
gpt4 key购买 nike

我正在利用 Context 的 useReducer 钩子(Hook)来创建支持中间件的 Redux-ish 状态存储。

const Provider = (props: any) => {
const [state, dispatch] = React.useReducer(reducer, {
title: 'Default title',
count: 0,
});

const actionDispatcher = makeActionDispatcher(
dispatch,
applyMiddleware(state, thunkMiddleware, callApiMiddleware, logger),
);

return (
<Context.Provider value={{ ...state, ...actionDispatcher }}>
{props.children}
</Context.Provider>
);
};

请注意,我将 state 传递给 applyMiddleware:

const applyMiddleware = (state: {}, ...middlewares: Function[]) =>
function dispatcher(dispatch: Function) {
const middlewareAPI = {
state,
dispatch: (...args) => dispatch(...args),
};
const chain = middlewares.map((middleware) => {
return middleware(middlewareAPI);
});
return compose(...chain)(dispatch);
};

这可行,但最终我希望能够使用异步操作,所以理想情况下我会有类似 redux-thunk 的东西:

function thunkMiddleware(store: Store) {
return (next: Function) => (action: any) => {
typeof action === 'function' ? action(next, store.getState) : next(action);
};
}

鉴于 thunk 中间件将作用于异步操作,理想情况下我们能够传递一个函数来在需要时检索当前状态 - getState - 而不是被迫使用存在的状态当应用中间件时,该中间件可能已经过时。

通常我会传递这样的内容:

const getState = () => React.useReducer(reducer, {
title: 'Default title',
count: 0,
})[0];

但是,如果我将其传递给要调用的中间件,我会收到一条错误,表明我可以 only call hooks from React functions .

我的架构是错误的吗?我是不是没有正确地将头绕在钩子(Hook)上?

更新:添加请求的makeActionDispatcher实现

export const makeActionDispatcher = (
dispatch: React.Dispatch<any> | undefined,
enhancer?: Function,
): ActionDispatcher => {
const actionDispatcher: { [key: string]: (...args: any) => void } = {};

Object.keys(actionCreators).forEach((key) => {
const creator = actionCreators[key];
actionDispatcher[key] = (...args: any) => {
if (!dispatch) {
throw new Error('ActionDispatcher has not been initialized!');
}

const action = creator(...args);

if (enhancer) {
const enhancedDispatch = enhancer(dispatch);
enhancedDispatch(action);
} else {
dispatch(action);
}
};
});

return actionDispatcher as ActionDispatcher;
};

最佳答案

使用引入的useEnhancedReducer钩子(Hook)here .

然后你就会得到类似的东西。

const [state, dispatch, getState] = useEnahancedReducer(reducer, initState)

因为 dispatchgetState 永远不会改变,所以您可以将其传递给某个钩子(Hook),而无需将它们添加到依赖列表中或将它们存储在其他地方以便从外部调用它们。

同一篇文章中还有一个支持添加中间件的 useEnhancedReducer 版本。

关于reactjs - 从 React 组件外部的 useReducer 检索当前状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55800345/

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