Redux Toolkit报错:Property 'user'不存在于WritableDraft类型
问题解决:Redux Toolkit userSlice类型错误与状态更新失败
核心问题拆解
- 类型不匹配:你定义的
UserState包含user字段,但slice的initialState只有profile,导致TS报错Property 'user' does not exist。 - 异步action未正确处理:你用了
createAsyncThunk创建异步获取用户的方法,但没在extraReducers里处理这个异步action的结果,反而在reducers里定义了同名同步action,完全没用到异步请求返回的数据。 - API返回结构不匹配:API返回的是
{user: {...}}格式,但你的类型定义和state更新逻辑没对应上这个结构。
修复步骤
1. 修正类型定义(client/src/interfaces/user.ts)
根据API返回的实际数据调整类型,让TS能正确识别结构:
// 对应API返回的user对象结构 export type UserData = { _id: string; ipAddress: string; createdAt: string; // 其他字段根据实际返回补充 }; // 对应API返回的整体结构 export type ApiUserResponse = { user: UserData; }; // Redux状态的类型 export type UserState = { user: UserData | null; // 初始设为null,更合理 loading: boolean; error: string | null; };
2. 重构userSlice(client/src/redux/features/userSlice.ts)
- 对齐
initialState和UserState类型 - 移除无用的同步reducer,改用
extraReducers处理异步action - 正确解析API返回的
payload.user:
import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit"; import { ApiUserResponse, UserData, UserState } from "../../interfaces/user"; import userApi from "../../apis/user"; export const getUser = createAsyncThunk<ApiUserResponse>( "user/getUser", async (_, thunkApi) => { try { const response = await userApi.getUser(); return response; } catch (error) { return thunkApi.rejectWithValue({ error: "获取用户数据失败" }); } } ); // 初始状态严格匹配UserState类型 const initialState: UserState = { user: null, loading: false, error: null, }; const userSlice = createSlice({ name: "user", initialState, reducers: {}, // 这里不需要同步action,移除之前的getUser extraReducers: (builder) => { builder .addCase(getUser.pending, (state) => { state.loading = true; state.error = null; }) .addCase(getUser.fulfilled, (state, action: PayloadAction<ApiUserResponse>) => { state.loading = false; // 提取API返回的user对象赋值给state.user state.user = action.payload.user; }) .addCase(getUser.rejected, (state, action) => { state.loading = false; state.error = action.payload?.error || "未知错误"; }); }, }); export default userSlice.reducer;
3. 优化API请求(client/src/apis/user.ts)
确保请求失败时正确抛出错误,而不是返回错误对象,这样createAsyncThunk能正确进入rejected状态:
const userApi = { getUser: async () => { const response = await fetch("http://localhost:5000/user/:ipAddress"); if (!response.ok) { throw new Error("请求用户数据失败"); } const user = await response.json(); console.log("in user api:", user); return user; }, }; export default userApi;
验证效果
现在调用getUser异步action后,Redux状态会正确更新:
- 请求中:
loading: true - 请求成功:
user字段被赋值为API返回的用户对象,包含ipAddress等信息 - 请求失败:
error字段会显示错误信息
内容的提问来源于stack exchange,提问作者Misha Krul
相关产品推荐
相关产品推荐

