[英]Unable to read state updated by useReducer hook in context provider
I am using useReducer
hook to manage my state, but it seems like I have a problem with reading updated state in my context provider.我正在使用useReducer
钩子来管理我的状态,但在我的上下文提供程序中读取更新状态似乎有问题。
My context provider is responsible to fetch some remote data and update the state based on responses:我的上下文提供程序负责获取一些远程数据并根据响应更新状态:
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;
and useAppState.js
is very simple as: 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;
The question is, as stated in the comment above, why is state.stateUpdated
in context provider's otherFunction
still false
and how could I access state with latest changes in the same function?现在的问题是,如上面的评论说,为什么state.stateUpdated
在上下文提供的otherFunction
还是false
,我怎么能访问相同的功能与最新的变化状态?
state
will never change in that function该函数中的state
永远不会改变The reason state
will never change in that function is that state
is only updated on re-render.究其原因state
将永远不会在该函数的变化是, state
只更新重新渲染。 Therefore, if you want to access state
you have two options:因此,如果您想访问state
您有两个选择:
useRef
to see a future value of state
(you'll have to modify your reducer to make this work) 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
after every state change so that it would see the most up-to-date state.您可以在每次状态更改后重置setInterval
,以便它看到最新的状态。 However, this means that your interval could get interrupted a lot.但是,这意味着您的间隔可能会中断很多。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]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.