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
相关产品推荐
相关产品推荐

