You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么Fetch API无法提交useReducer更新后的最新状态?

你的问题出在useMemo的依赖配置和变量声明顺序上,具体原因和修复方案如下:

问题根源

  1. 变量声明顺序错误:你在声明useMemo的时候,loginState和dispatch还没有通过useReducer创建,此时引用的是未定义/初始旧值。
  2. useMemo依赖数组为空:useMemo只会在组件首次渲染时计算一次authContext,内部的signIn方法形成了闭包,永远捕获的是首次渲染时的loginState初始值(也就是email为null的状态),哪怕后续你通过dispatch更新了loginState,authContext也不会重新生成,所以提交的永远是旧数据。

修复步骤

  1. 把useReducer的声明移到useMemo之前,确保useMemo可以拿到正确的dispatch和loginState引用。
  2. 在useMemo的依赖数组中加入loginState,这样每当loginState更新时,authContext就会重新计算,signIn方法就能拿到最新的状态值。
  3. 可选优化:给fetch加await,同时补充HTTP状态判断,避免接口报错无法捕获的问题。

修正后的App.js代码

import React from 'react';
import AuthContext from './context';
import ScreenA from './screenA'; // 组件名建议首字母大写,符合React规范

export default function App() {
  const initialLoginState = {
    email: null,
  };
  const loginReducer = (prevState, action) => {
    switch (action.type) {
      case 'Email':
        return {
          ...prevState,
          email: action.Email,
        };
      default:
        return prevState; // 建议加default分支处理未知action
    }
  };

  // 先声明useReducer,再用useMemo
  const [loginState, dispatch] = React.useReducer(
    loginReducer,
    initialLoginState,
  );

  const authContext = React.useMemo(
    () => ({
      email: emailUser => {
        dispatch({type: 'Email', Email: emailUser});
      },
      signIn: async () => {
        try {
          const response = await fetch('FakeApi', {
            method: 'POST',
            headers: {
              Accept: 'application/json',
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              email: loginState.email,
              date: '2021-9-20',
            }),
          });
          if (!response.ok) throw new Error('接口请求失败');
          const data = await response.json();
          // 后续处理登录成功逻辑
        } catch (e) {
          console.log(e);
        }
      },
    }),
    [loginState], // 加入loginState作为依赖
  );

  return (
    <AuthContext.Provider value={authContext}>
      <ScreenA />
    </AuthContext.Provider>
  );
}

内容的提问来源于stack exchange,提问作者Ali Mahmoudi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 23:45:01