来自 react-router-dom 的 useRouteError() 中的错误的正确类型是什么?



我在React项目中使用React -router-dom中的useRouteError()钩子来捕获路由过程中可能发生的任何错误。但是,我不确定这个钩子返回的错误对象的正确类型是什么。

现在,我在组件中将错误声明为any,这并不理想。我想为错误对象声明正确的类型,以使我的代码更健壮。

有人能告诉我什么是正确的类型是由useRouteError()在react-router-dom返回的错误对象?

import { useRouteError } from 'react-router-dom'
const ErrorPage: React.FC = () => {
const error: any = useRouteError() // Add appropriate type here
return (
<div
id='error-page'
className='flex flex-col gap-8 justify-center items-center h-screen'
>
<h1 className='text-4xl font-bold'>Oops!</h1>
<p>Sorry, an unexpected error has occurred.</p>
<p className='text-slate-400'>
<i>{error.statusText || error.message}</i>
</p>
</div>
)
}
export default ErrorPage

useRouteError具有正确的unknown类型,因为您可以从加载器或操作中抛出任何内容。你应该像React Router的一个维护者建议的那样,使用类型缩小来推断错误类型。

下面是一个如何使用isRouteErrorResponse(error)助手方法的示例:
(注意您不需要显式地将error设置为unknown)

import React from 'react';
import { useRouteError, isRouteErrorResponse } from 'react-router-dom';
const ErrorPage: React.FC = () => {
// you don't need to explicitly set error to `unknown`
const error = useRouteError();
let errorMessage: string;
if (isRouteErrorResponse(error)) {
// error is type `ErrorResponse`
errorMessage = error.error?.message || error.statusText;
} else if (error instanceof Error) {
errorMessage = error.message;
} else if (typeof error === 'string') {
errorMessage = error;
} else {
console.error(error);
errorMessage = 'Unknown error';
}
return (
<div id='error-page' className='flex flex-col gap-8 justify-center items-center h-screen'>
<h1 className='text-4xl font-bold'>Oops!</h1>
<p>Sorry, an unexpected error has occurred.</p>
<p className='text-slate-400'>
<i>{errorMessage}</i>
</p>
</div>
);
};
export default ErrorPage;

谢谢,我已经解决了这样的错误

tsconfig的编译器选项useUnknownInCatchVariables: true中添加此选项。

import { useRouteError } from 'react-router-dom'
const ErrorPage: React.FC = () => {
const error: unknown = useRouteError()
return (
<div
id='error-page'
className='flex flex-col gap-8 justify-center items-center h-screen'
>
<h1 className='text-4xl font-bold'>Oops!</h1>
<p>Sorry, an unexpected error has occurred.</p>
<p className='text-slate-400'>
<i>
{(error as Error)?.message ||
(error as { statusText?: string })?.statusText}
</i>
</p>
</div>
)
}
export default ErrorPage

可以这样使用

import {
useNavigate,
isRouteErrorResponse,
useRouteError,
} from 'react-router-dom';
export const Error = () => {
const navigate = useNavigate();
const error = useRouteError() as Error;
if (!isRouteErrorResponse(error)) {
return null;
}

return (
<div>
<h1>Something went wrong 😢</h1>
<p>{error.data}</p>
<button onClick={() => navigate(-1)}>&larr; Go back</button>
</div>
);
};

可以使用与函数isRouteErrorResponse相同的参数类型;ErrorResponse,可以从"@remix-run/router/utils.ts";

导入
import { isRouteErrorResponse, useRouteError } from "react-router-dom";
import {ErrorResponse} from "@remix-run/router/utils.ts";
import NotFound from './NotFound'
export default function ErrorPage() {
const error = useRouteError() as ErrorResponse;
if (isRouteErrorResponse(error)) {
if (error.status === 404) {
return <NotFound />
}
}
return (
<div id="error-page">
<h1>Oops!</h1>
<p>Sorry, an unexpected error has occurred.</p>
<p>
<i>{error?.status || error?.error?.message}</i>
</p>
</div>
);
}