React TypeScript中Context API存储用户信息报错求助
React + TypeScript Context API 报错修复
核心问题分析
Context初始值类型不匹配
你定义的UserAuthContext类型是包含state和dispatch的对象,但初始化时传入的INITIAL_STATE仅包含userInfo字段,TypeScript检测到类型结构不匹配,触发报错。Reducer返回状态与AppState类型冲突
AppState被定义为typeof INITIAL_STATE,也就是仅包含userInfo: string | null,但你的reducer返回的状态里包含loading、success、error等额外字段,导致类型不兼容。
修复步骤及完整代码
1. 定义完整的AppState接口
替换原来的type AppState = typeof INITIAL_STATE,手动声明所有可能的状态字段:
interface AppState { userInfo: string | null; loading: boolean; success: boolean; error?: string; }
2. 更新INITIAL_STATE的初始值
确保初始状态包含所有字段的默认值,符合AppState类型:
const INITIAL_STATE: AppState = { userInfo: localStorage.getItem("userInfo") || null, loading: false, success: false, };
3. 修正Context的初始值
提供符合{state: AppState; dispatch: React.Dispatch<Action>}类型的初始值,用空函数作为初始dispatch(实际使用时会被useReducer的dispatch替换):
const UserAuthContext = createContext<{ state: AppState; dispatch: React.Dispatch<Action>; }>({ state: INITIAL_STATE, dispatch: () => {}, });
4. 修复Reducer的返回逻辑
避免直接返回新对象丢失原有状态,使用扩展运算符...state保留原有字段,仅更新需要修改的部分:
const userLoginreducer = (state: AppState, action: Action): AppState => { switch (action.type) { case "USER_LOGIN_REQUEST": return { ...state, loading: true, error: undefined }; case "USER_LOGIN_SUCCESS": return { ...state, loading: false, success: true, userInfo: action.payload, error: undefined }; case "USER_LOGIN_FAIL": return { ...state, loading: false, error: action.payload, success: false }; default: return state; } };
完整修复后代码
import { createContext, useReducer, ReactNode } from "react"; type Action = | { type: "USER_LOGIN_REQUEST"; } | { type: "USER_LOGIN_SUCCESS"; payload: string } | { type: "USER_LOGIN_FAIL"; payload: string }; interface UserAuthProviderProps { children: ReactNode; } interface AppState { userInfo: string | null; loading: boolean; success: boolean; error?: string; } const INITIAL_STATE: AppState = { userInfo: localStorage.getItem("userInfo") || null, loading: false, success: false, }; const userLoginreducer = (state: AppState, action: Action): AppState => { switch (action.type) { case "USER_LOGIN_REQUEST": return { ...state, loading: true, error: undefined }; case "USER_LOGIN_SUCCESS": return { ...state, loading: false, success: true, userInfo: action.payload, error: undefined }; case "USER_LOGIN_FAIL": return { ...state, loading: false, error: action.payload, success: false }; default: return state; } }; const UserAuthContext = createContext<{ state: AppState; dispatch: React.Dispatch<Action>; }>({ state: INITIAL_STATE, dispatch: () => {}, }); function UserAuthProvider({ children }: UserAuthProviderProps) { const [state, dispatch] = useReducer(userLoginreducer, INITIAL_STATE); return ( <UserAuthContext.Provider value={{ state, dispatch }}> {children} </UserAuthContext.Provider> ); } export { UserAuthContext, UserAuthProvider };
内容的提问来源于stack exchange,提问作者Veera Silamban
相关产品推荐
相关产品推荐

