如何通过react-router-dom的navigate传递接口实例参数?
问题场景
我使用useNavigate跳转页面时,需要传递一个Api接口实例作为参数,相关代码如下:
Api接口定义
export interface Api { apiDescription: string; apiName: string; documentId: string; }
跳转组件代码
const { api, refresh } = props; const navigate = useNavigate(); return ( <div className="view-button-block"> <Button size="small" sx={{ color: "#000000DE", bgcolor: "#D9D9D6" }} onClick={() => navigate("/managementUi/viewApi", { state: api })} > View </Button> </div> );
目标组件(viewApi.tsx)代码
import React from "react"; import { useLocation } from 'react-router-dom'; import { Api } from '../../../common/Api.types'; const ViewApi = () => { const location = useLocation(); console.log(location.state); const api: Api = location.state; return ( <div> {location.state.apiName} </div> ); };
遇到的错误
跳转后在目标组件中读取location.state.apiName时,触发**"Object is of type 'unknown'"错误;将state赋值给Api类型变量时,触发"type unknown is not assignable to type Api"**错误。
解决方法
React Router的location.state默认类型为unknown,需要通过类型断言或类型守卫处理类型匹配问题,以下是三种可行方案:
方案1:类型断言+空值判断(快速实现)
直接将location.state断言为Api类型,同时增加空值判断避免null场景:
import React from "react"; import { useLocation } from 'react-router-dom'; import { Api } from '../../../common/Api.types'; const ViewApi = () => { const location = useLocation(); // 断言为Api类型并处理空值 const api = location.state as Api | null; if (!api) { return <div>缺少API数据</div>; } return ( <div> {api.apiName} </div> ); };
方案2:自定义类型守卫(类型安全)
通过类型守卫函数严格校验state是否符合Api接口规范,适合对类型严谨性要求高的场景:
import React from "react"; import { useLocation } from 'react-router-dom'; import { Api } from '../../../common/Api.types'; // 自定义类型守卫函数 function isApi(data: unknown): data is Api { return ( typeof data === 'object' && data !== null && 'apiDescription' in data && typeof (data as Api).apiDescription === 'string' && 'apiName' in data && typeof (data as Api).apiName === 'string' && 'documentId' in data && typeof (data as Api).documentId === 'string' ); } const ViewApi = () => { const location = useLocation(); const api = location.state; if (!isApi(api)) { return <div>API数据格式错误</div>; } return ( <div> {api.apiName} </div> ); };
方案3:全局扩展React Router类型(批量场景)
如果项目中多次需要传递该类型参数,可全局扩展LocationState类型,避免重复断言:
- 在项目根目录创建
src/types/react-router.d.ts文件 - 添加类型定义:
import { Api } from '../common/Api.types'; declare module 'react-router-dom' { interface LocationState { api: Api; } }
- 目标组件中直接使用:
import React from "react"; import { useLocation } from 'react-router-dom'; import { Api } from '../../../common/Api.types'; const ViewApi = () => { const location = useLocation(); const api = location.state.api; if (!api) { return <div>缺少API数据</div>; } return ( <div> {api.apiName} </div> ); };
内容的提问来源于stack exchange,提问作者Henry Bai
相关产品推荐
相关产品推荐

