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

Redux Toolkit报错:Property 'user'不存在于WritableDraft类型

问题解决:Redux Toolkit userSlice类型错误与状态更新失败

核心问题拆解

  1. 类型不匹配:你定义的UserState包含user字段,但slice的initialState只有profile,导致TS报错Property 'user' does not exist。
  2. 异步action未正确处理:你用了createAsyncThunk创建异步获取用户的方法,但没在extraReducers里处理这个异步action的结果,反而在reducers里定义了同名同步action,完全没用到异步请求返回的数据。
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 11:07:01