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

如何在React TypeScript+Redux Toolkit中存储后端返回的全部用户数据

问题:React TypeScript + Redux Toolkit 无法存储完整用户数据

我使用React TypeScript搭配Redux Toolkit,在获取用户信息时遇到问题:state.user只能存储单个值,希望它能存储后端返回的全部用户数据。

现有代码

userSlice.ts

export const userSlice = createSlice({
  name: "user",
  initialState: {
    user: null,
  },
  reducers: {
    setUser: (state, action) => {
      state.user = action.payload;
    },
   
  },
});

protectedRoute.tsx(部分代码)

export function ProtectedRoute(props: { children: any }) {
  const {user} = useSelector((state: any) => state.user);

  const dispatch = useDispatch();
  const navigate = useNavigate();
  const getUser = async () => {
    try {
      dispatch(showLoading());
      const response = await axios.post(
        "/api/users/user",
        { token: localStorage.getItem("token") },
        {
          headers: {
            Authorization: `Bearer ${localStorage.getItem("token")}`,
          },
        }
      );
      dispatch(hideLoading());
      if (response.data.success) {
        console.log(response.data.data.isAdmin);
        dispatch(setUser(response.data.data));

解决方案

1. 定义用户数据类型(TypeScript类型约束)

先明确后端返回的用户结构,创建对应的TypeScript接口,避免any导致的类型模糊问题:

// 根据后端实际返回的字段调整
interface User {
  id: string;
  username: string;
  isAdmin: boolean;
  email?: string; // 可选字段示例
  // 补充其他用户字段
}

2. 更新userSlice的类型与逻辑

将initialState和reducer的payload都加上类型约束,确保可以接收完整的用户对象:

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface User {
  id: string;
  username: string;
  isAdmin: boolean;
  // 补充后端返回的所有字段
}

interface UserState {
  user: User | null;
}

const initialState: UserState = {
  user: null,
};

export const userSlice = createSlice({
  name: "user",
  initialState,
  reducers: {
    setUser: (state, action: PayloadAction<User>) => {
      // 直接赋值完整的payload对象,即可存储全部用户数据
      state.user = action.payload;
    },
  },
});

export const { setUser } = userSlice.actions;
export default userSlice.reducer;

3. 优化ProtectedRoute的类型使用

从store中导出RootState类型,替代any,让TypeScript做类型校验:

// 首先在store.ts中导出RootState和AppDispatch类型
// store.ts示例代码:
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './userSlice';

export const store = configureStore({
  reducer: {
    user: userReducer,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

然后在ProtectedRoute中使用这些类型:

import { RootState, AppDispatch } from './store';
import { useDispatch, useSelector } from 'react-redux';
import { useEffect } from 'react';

export function ProtectedRoute(props: { children: React.ReactNode }) {
  const { user } = useSelector((state: RootState) => state.user);
  const dispatch = useDispatch<AppDispatch>();
  const navigate = useNavigate();

  const getUser = async () => {
    try {
      dispatch(showLoading());
      const response = await axios.post(
        "/api/users/user",
        { token: localStorage.getItem("token") },
        {
          headers: {
            Authorization: `Bearer ${localStorage.getItem("token")}`,
          },
        }
      );
      dispatch(hideLoading());
      if (response.data.success) {
        // 确认response.data.data是完整用户对象
        console.log('完整用户数据:', response.data.data);
        dispatch(setUser(response.data.data));
      }
    } catch (error) {
      dispatch(hideLoading());
      navigate('/login'); // 请求失败跳转登录
    }
  };

  useEffect(() => {
    if (!user) {
      getUser();
    }
  }, [user, navigate, dispatch]);

  return user ? props.children : <div>加载中...</div>;
}

4. 验证后端返回数据

确保后端接口/api/users/user返回的response.data.data是包含所有用户字段的对象,而非单个值。如果后端返回的是数组或其他结构,需要对应调整User类型和slice的处理逻辑。


内容的提问来源于stack exchange,提问作者Ahmed Ben Bettaieb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:40:39