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

React自定义Hook类型错误:无法获取doRequest与errors类型

解决React+TypeScript自定义Hook useRequest的类型错误

错误原因分析

  1. 自定义Hook误用React.FC类型:React.FC是专门用于定义返回JSX的React函数组件的类型,而你的useRequest是自定义Hook,返回的是包含doRequest和errors的普通对象,类型完全不匹配。这个错误直接引发了Hook自身的类型报错,同时让TypeScript错误推断Hook的返回值为ReactElement<any, any> | null,导致解构时找不到doRequest和errors的属性。
  2. Hook未返回指定对象:原useRequest代码里缺少return { doRequest, errors }语句,TypeScript无法识别返回值的结构,进一步加剧了类型推断错误。

解决方案

1. 修正useRequest的类型定义与返回逻辑

去掉React.FC<UseRequestProps>的错误类型标注,直接定义函数参数类型,同时可以显式声明返回值接口让类型检查更严谨:

import axios from "axios";
import React, { ReactElement, useState } from "react";
import classes from "../components/errors/errors.module.css";

interface UseRequestProps {
  url: string;
  method: "post" | "get" | "put" | "delete";
  body?: any;
  onSuccess?: () => void;
}

// 显式定义Hook的返回值类型
interface UseRequestReturn {
  doRequest: () => Promise<void>;
  errors: ReactElement | null;
}

const useRequest = ({ url, method, body, onSuccess }: UseRequestProps): UseRequestReturn => {
  const [errors, setErrors] = useState<ReactElement | null>(null);

  const doRequest = async () => {
    try {
      await axios({
        url,
        method,
        data: body
      });
      setErrors(null);
      onSuccess?.();
    } catch (err: any) {
      // 示例:渲染后端返回的错误列表
      setErrors(
        <div className={classes.errors}>
          {err.response?.data?.errors?.map((error: { message: string }) => (
            <div key={error.message}>{error.message}</div>
          ))}
        </div>
      );
    }
  };

  // 必须返回包含doRequest和errors的对象
  return { doRequest, errors };
};

export default useRequest;

2. AuthForm组件正常使用即可

修正Hook后,原组件的解构错误会自动消失,这里补充完整的组件示例供参考:

import classes from "./auth-form.module.css";
import { useState } from "react";
import useRequest from "../../hooks/use-request";

const AuthForm = () => {
  const [email, setEmail] = useState<string>("");
  const [password, setPassword] = useState<string>("");
  const { doRequest, errors } = useRequest({
    url: "/api/users/signup",
    method: "post",
    body: {
      email,
      password,
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    doRequest();
  };

  return (
    <form className={classes.form} onSubmit={handleSubmit}>
      {errors}
      <div className={classes.control}>
        <label htmlFor="email">邮箱</label>
        <input
          type="email"
          id="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          required
        />
      </div>
      <div className={classes.control}>
        <label htmlFor="password">密码</label>
        <input
          type="password"
          id="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          required
        />
      </div>
      <button className={classes.button}>注册</button>
    </form>
  );
};

export default AuthForm;

关键注意点

  • 自定义Hook绝对不能使用React.FC类型,FC仅适用于返回JSX的函数组件。
  • 显式定义Hook的返回值类型,能让TypeScript更精准地做类型检查,避免隐式推断错误。
  • 必须确保Hook返回你需要的对象结构,缺失return语句会直接导致类型识别失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:05:38