无法读取上下文提供程序中的 useReducer 挂钩更新的状态



我正在使用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则有两种选择:

  1. 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];
  1. 您可以在每次状态更改后重置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]);

相关内容

  • 没有找到相关文章

最新更新