React异步函数中获取URL参数失败的问题咨询
如何在React异步函数中获取URL参数?
问题场景与报错信息
路由配置
return ( <BrowserRouter> <Routes> <Route path="/signin/:projectUUID" element={<SignIn />} />
异步函数代码(尝试获取参数)
export const EmailSendEmailMagicLink = async (callback) => { let resultState = { state: '', data: {} }; const { projectUUID } = this.props; // 第45行 let project_uuid = projectUUID ? projectUUID : "";
函数调用位置
const EmailSignInBtn = async (form_data, file) => { let result = await EmailSendEmailMagicLink();
对应HTML元素
<Box className='signup-Btn' onClick={EmailSignInBtn}> Get Magic Link </Box>
首次报错信息
ApiProvider.js:45 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'props') at EmailSendEmailMagicLink (ApiProvider.js:45:1) at EmailSignInBtn (signIn.js:42:1) at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1) at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1) at invokeGuardedCallback (react-dom.development.js:4277:1) at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1) at executeDispatch (react-dom.development.js:9041:1) at processDispatchQueueItemsInOrder (react-dom.development.js:9073:1) at processDispatchQueue (react-dom.development.js:9086:1) at dispatchEventsForPlugins (react-dom.development.js:9097:1)
使用useParams后的报错
尝试在异步函数内直接调用useParams:
const { projectUUID } = useParams(); let project_uuid = projectUUID ? projectUUID : "";
报错信息:
Uncaught (in promise) Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks
解决方法
问题根源:
- 普通异步函数不是类组件方法,
this.props的this指向undefined,无法获取参数; useParams是React Hook,必须在函数组件的顶层作用域调用,不能放在异步函数或嵌套函数内。
方案一:将URL参数作为参数传递给异步函数(推荐)
- 在
SignIn组件顶层调用useParams获取参数,再传递给异步函数:
// SignIn组件内部 import { useParams } from 'react-router-dom'; const SignIn = () => { // 必须在组件顶层调用Hook const { projectUUID } = useParams(); const EmailSignInBtn = async (form_data, file) => { // 将参数传入目标异步函数 let result = await EmailSendEmailMagicLink(projectUUID); }; return ( <Box className='signup-Btn' onClick={EmailSignInBtn}> Get Magic Link </Box> ); };
- 修改
EmailSendEmailMagicLink函数,接收传入的参数:
export const EmailSendEmailMagicLink = async (projectUUID, callback) => { let resultState = { state: '', data: {} }; let project_uuid = projectUUID ? projectUUID : ""; // 后续业务逻辑 };
方案二:手动解析浏览器URL获取参数
如果不想依赖React Router的Hook,可以直接从浏览器地址栏解析参数:
export const EmailSendEmailMagicLink = async (callback) => { let resultState = { state: '', data: {} }; // 拆分路径获取最后一段的projectUUID const pathSegments = window.location.pathname.split('/'); const projectUUID = pathSegments[pathSegments.length - 1]; let project_uuid = projectUUID ? projectUUID : ""; // 后续业务逻辑 };
注意:此方法依赖固定的路由路径结构,如果路由路径修改,解析逻辑也需要同步调整,灵活性不如方案一。
内容的提问来源于stack exchange,提问作者london_utku
相关产品推荐
相关产品推荐

