无法读取上下文提供程序中的 useReducer 挂钩更新的状态
Posted
技术标签:
【中文标题】无法读取上下文提供程序中的 useReducer 挂钩更新的状态【英文标题】:Unable to read state updated by useReducer hook in context provider 【发布时间】:2019-08-23 22:21:07 【问题描述】:我正在使用 useReducer
挂钩来管理我的状态,但我在上下文提供程序中读取更新状态时似乎遇到了问题。
我的上下文提供者负责获取一些远程数据并根据响应更新状态:
import React, useEffect from 'react';
import useAppState from './useAppState';
export const AppContext = React.createContext();
const AppContextProvider = props =>
const [state, dispatch] = useAppState();
const initialFunction = () =>
fetch('/some_path')
.then(res =>
dispatch( type: 'UPDATE_STATE', res );
);
;
const otherFunction = () =>
fetch('/other_path')
.then(res =>
// why is `state.stateUpdated` here still 'false'????
dispatch( type: 'DO_SOMETHING_ELSE', res );
);
;
const actions = initialFunction, otherFunction ;
useEffect(() =>
initialFunction();
setInterval(otherFunction, 30000);
, []);
return (
<AppContext.Provider value= state, actions >
props.children
</AppContext.Provider>
)
;
export default AppContextProvider;
而useAppState.js
很简单:
import useReducer from 'react';
const useAppState = () =>
const reducer = (state, action) =>
switch (action.type)
case 'UPDATE_STATE':
return
...state,
stateUpdated: true,
;
case 'DO_SOMETHING_ELSE':
return
...state,
// whatever else
;
default:
throw new Error();
;
const initialState = stateUpdated: false ;
return useReducer(reducer, initialState);
;
export default useAppState;
问题是,如上面的评论所述,为什么上下文提供者的otherFunction
中的state.stateUpdated
仍然是false
,我如何通过同一函数的最新更改访问状态?
【问题讨论】:
【参考方案1】:
state
在该函数中永远不会改变
state
在该函数中永远不会改变的原因是state
仅在重新渲染时更新。因此,如果您想访问state
,您有两种选择:
useRef
以查看 state
的未来值(您必须修改减速器才能使其工作)
const updatedState = useRef(initialState);
const reducer = (state, action) =>
let result;
// Do your switch but don't return, just modify result
updatedState.current = result;
return result;
;
return [...useReducer(reducer, initialState), updatedState];
-
您可以在每次状态更改后重置您的
setInterval
,以便它可以看到最新的状态。但是,这意味着您的间隔可能会被打断很多。
const otherFunction = useCallback(() =>
fetch('/other_path')
.then(res =>
// why is `state.stateUpdated` here still 'false'????
dispatch( type: 'DO_SOMETHING_ELSE', res );
);
, [state.stateUpdated]);
useEffect(() =>
const id = setInterval(otherFunction, 30000);
return () => clearInterval(id);
, [otherFunction]);
【讨论】:
@errata 如果答案对您有用,请不要忘记将其标记为答案。 嘿,抱歉,之前没有机会尝试这个。我采用了第一种方法,在我的用例中似乎更容易实现,但是,我仍然没有在我的示例中看到otherFunction()
范围内的更新状态,但我确实看到它超出了它的范围。我不得不承认我不太明白为什么会这样,你呢?我应该在我的上下文提供程序中以同样的方式使用useAppState()
,对吧?
你使用了updatedState
从useAppState
返回的第三个变量吗?是的,您的上下文提供者应该是相同的
啊,对了,我就知道这是微不足道的事情。现在知道了,非常感谢您的回答和所有解释!
真的很高兴你分享这个答案!您的第一个选项确实为我节省了很多时间和精力。谢谢!以上是关于无法读取上下文提供程序中的 useReducer 挂钩更新的状态的主要内容,如果未能解决你的问题,请参考以下文章
在 React 中使用 useContext 和 useReducer 创建新的键值对
如何测试组件中的react useContext useReducer调度
使用 useContext useReducer 基本示例反应登录
如何为以下 contextapi 代码的 useReducer useContext 设置 Typescript 类型?