无法读取上下文提供程序中 useReducer 挂钩更新的状态
Unable to read state updated by useReducer hook in context provider
我正在使用 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
以及我如何访问同一函数中最新更改的状态?
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]);
我正在使用 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
以及我如何访问同一函数中最新更改的状态?
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]);