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

TypeScript中使用Context API实现用户登录时Provider报错排查

问题原因及修复方案

核心错误点

  • 状态结构不一致:Reducer中LOGIN返回的是带有_currentUser和存取器的对象,而LOGOUT和初始状态INITIAL_STATE直接返回包含currentUser属性的对象,结构不统一会导致组件访问state.currentUser时出现异常。
  • 误用存取器:React的useReducer要求状态是纯数据对象,存取器(getter/setter)会破坏状态的不可变性原则,还会干扰React基于浅比较的更新判断逻辑。
  • 类型定义不匹配:State接口明确了currentUser属性,但LOGIN返回的对象没有直接该属性,而是通过getter提供;加上Reducer的state参数用any掩盖了类型错误,导致类型检查失效。

修复后的代码

修正AuthReducer

export const AuthReducer = (state: { currentUser: any }, action: { type: string; payload: any; }) => {
    switch (action.type) {
        case "LOGIN": {
            // 保持状态结构一致,直接返回包含currentUser的纯对象
            return {
                ...state,
                currentUser: action.payload
            };
        }
        case "LOGOUT": {
            return {
                ...state,
                currentUser: null
            };
        }
        default:
            return state;
    }
}

优化类型定义(可选但推荐)

如果要完善类型检查,可以给Action定义明确类型,同时严格限制State类型:

// AuthReducer.ts
export type AuthAction = 
    | { type: "LOGIN"; payload: any }
    | { type: "LOGOUT" };

export const AuthReducer = (state: { currentUser: any }, action: AuthAction) => {
    switch (action.type) {
        case "LOGIN": {
            return {
                ...state,
                currentUser: action.payload
            };
        }
        case "LOGOUT": {
            return {
                ...state,
                currentUser: null
            };
        }
        default:
            return state;
    }
}
// AuthContext.ts
import { createContext, useReducer } from "react";
import { AuthReducer, AuthAction } from "./AuthReducer";
import React, { ReactNode } from "react";

interface State {
  currentUser: any; 
}

interface AuthContextType {
  currentUser: State["currentUser"];
  dispatch: React.Dispatch<AuthAction>; 
}

interface AuthContextProviderProps {
  children: ReactNode;
}

const INITIAL_STATE: State = {
  currentUser: null,
}

export const AuthContext = createContext<AuthContextType>({
  currentUser: INITIAL_STATE.currentUser,
  dispatch: () => {}, 
});

export const AuthContextProvider: React.FC<AuthContextProviderProps> = ({
  children
}) => {
  const [state, dispatch] = useReducer(AuthReducer, INITIAL_STATE);

  return (
    <AuthContext.Provider value={{ currentUser: state.currentUser, dispatch }}>
      {children}
    </AuthContext.Provider>
  );
};

内容的提问来源于stack exchange,提问作者Frederick Ottache

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:05:10