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

Next.js中TypeScript版REST API HOC包裹组件后无法读取用户数据

解决Next.js中withUser HOC无法传递user数据的问题

问题分析

你的TS版本HOC存在几个潜在问题导致user数据无法正确传递到页面组件:

  • 请求header键名错误:contentType应改为标准的Content-Type
  • 错误处理不完整:非401的请求错误会导致user保持初始null,触发不必要重定向
  • 类型定义缺失:大量使用any会引发TS类型推断异常,且Next.js的getInitialProps上下文未使用正确类型
  • 重定向后未终止函数执行:虽调用了res.end(),但需补充return确保函数不再继续执行

修正后的withUser.tsx代码

import axios, { AxiosError } from "axios";
import { API } from "../config";
import { getCookie } from "../helpers/auth";
import type { NextPage, NextPageContext } from "next";

// 定义用户数据类型,根据实际API返回结构调整
interface User {
  first_name: string;
  // 可添加其他字段如last_name、email等
}

// 定义HOC注入的props类型
interface WithUserInjectedProps {
  user: User;
  token: string;
  userLinks: string[];
}

const withUser = <P extends object>(Page: NextPage<P & WithUserInjectedProps>) => {
  const WithAuthUser: NextPage<P> = (props) => <Page {...props as P & WithUserInjectedProps} />;

  WithAuthUser.getInitialProps = async (context: NextPageContext): Promise<P | void> => {
    const token = getCookie("token", context.req);
    let user: User | null = null;
    let userLinks: string[] = [];

    if (token) {
      try {
        const response = await axios.get(`${API}/user`, {
          headers: {
            Authorization: `Bearer ${token}`,
            "Content-Type": "application/json",
          },
        });

        user = response.data.user;
        userLinks = response.data.links;
      } catch (err: unknown) {
        const error = err as AxiosError;
        if (error.response?.status === 401) {
          user = null;
        } else {
          console.error("获取用户信息失败:", error);
          user = null;
        }
      }
    }

    if (user === null) {
      // 兼容服务端与客户端重定向
      if (context.res) {
        context.res.writeHead(302, { Location: "/" });
        context.res.end();
      } else {
        import("next/router").then(({ default: router }) => router.push("/"));
      }
      return;
    }

    // 获取页面自身的初始props
    const pageProps = await Page.getInitialProps?.(context) || {};

    return {
      ...pageProps,
      user,
      token,
      userLinks,
    } as P;
  };

  return WithAuthUser;
};

export default withUser;

修正后的User页面代码

import withUser from "../withUser";
import type { User } from "../withUser";

interface UserPageProps {
  user: User;
}

const User = ({ user }: UserPageProps) => (
  <div className="flex min-h-screen flex-col items-center justify-center">
    {user.first_name}
  </div>
);

export default withUser(User);

关键改进点

  • 类型安全:添加明确类型定义,避免any带来的类型推断问题
  • Header规范:修正请求头键名,确保服务器正确解析请求
  • 完善错误处理:覆盖非401错误场景,补充客户端重定向逻辑
  • 函数终止:重定向后添加return,避免后续代码执行引发异常
  • 泛型支持:使用泛型兼容页面自身props,提升HOC复用性

内容的提问来源于stack exchange,提问作者Jerald Baroro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:48:10