React自定义Hook类型错误:无法获取doRequest与errors类型
解决React+TypeScript自定义Hook useRequest的类型错误
错误原因分析
- 自定义Hook误用React.FC类型:
React.FC是专门用于定义返回JSX的React函数组件的类型,而你的useRequest是自定义Hook,返回的是包含doRequest和errors的普通对象,类型完全不匹配。这个错误直接引发了Hook自身的类型报错,同时让TypeScript错误推断Hook的返回值为ReactElement<any, any> | null,导致解构时找不到doRequest和errors的属性。 - 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
相关产品推荐
相关产品推荐

