React.js中URL路径参数获取问题:match未定义及useParams使用困惑
React Router v6 获取URL参数报错:Uncaught TypeError: n is undefined
在React应用中尝试通过match获取URL路径中的uid和token参数时,出现以下错误:
Uncaught TypeError: n is undefined
最初的代码片段:
const ResetPasswordConfirm = ( {match, reset_password_confirm} ) => { ... const onSubmit = e=> { e.preventDefault(); const uid = match.params.uid; const token = match.params.token; reset_password_confirm(uid, token, new_password, re_new_password); setRequestSent(true); }; };
环境信息
- react-router-dom版本:6.8.0
- 组件使用
connect连接Redux,完整代码如下:
import React, { useState } from "react"; import { Navigate, useParams } from 'react-router-dom'; import { connect } from 'react-redux'; import { reset_password_confirm } from '../actions/auth'; const ResetPasswordConfirm = ( {match, reset_password_confirm} ) => { const [requestSent, setRequestSent] = useState(false); const [formData, setFormData] = useState({ new_password: '', re_new_password: '' }); const { new_password, re_new_password } = formData; const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value }); const onSubmit = e=> { e.preventDefault(); const uid = match.params.uid; const token = match.params.token; reset_password_confirm(uid, token, new_password, re_new_password); setRequestSent(true); }; if (requestSent) { return <Navigate to='/'/> } return ( <div className="container mt-5"> <form onSubmit={e => onSubmit(e)}> <div className="form-group"> <label htmlFor="exampleInputPassword1">Password</label> <input type="password" className="form-control" id="exampleInputPassword1" placeholder="New Password" name="new_password" value={new_password} onChange={e => onChange(e)} minLength='6' required></input> </div> <div className="form-group"> <label htmlFor="exampleInputPassword1">Password</label> <input type="password" className="form-control" id="exampleInputPassword1" placeholder="Confirm New Password" name="re_new_password" value={re_new_password} onChange={e => onChange(e)} minLength='6' required></input> </div> <button type="submit" className="btn btn-primary">Reset Password</button> </form> </div> ); }; export default connect(null, { reset_password_confirm }) (ResetPasswordConfirm);
尝试过在onSubmit中调用useParams,但用法错误:
const onSubmit = e => { ... let{uid} = useParams() }
解决方案
React Router v6 彻底移除了通过组件props传递match、location、history的方式,必须使用对应的Hook获取参数,且Hook只能在组件顶层调用,不能在事件回调、嵌套函数中使用。
修改步骤:
- 移除组件参数中的
match,因为v6不会再传递这个props - 在组件顶层调用
useParams()获取URL参数 - 在
onSubmit中直接使用获取到的参数
修改后的完整代码:
import React, { useState } from "react"; import { Navigate, useParams } from 'react-router-dom'; import { connect } from 'react-redux'; import { reset_password_confirm } from '../actions/auth'; // 移除props中的match const ResetPasswordConfirm = ( { reset_password_confirm} ) => { // 在组件顶层调用useParams获取参数 const { uid, token } = useParams(); const [requestSent, setRequestSent] = useState(false); const [formData, setFormData] = useState({ new_password: '', re_new_password: '' }); const { new_password, re_new_password } = formData; const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value }); const onSubmit = e=> { e.preventDefault(); // 直接使用顶层获取到的uid和token reset_password_confirm(uid, token, new_password, re_new_password); setRequestSent(true); }; if (requestSent) { return <Navigate to='/'/> } return ( <div className="container mt-5"> <form onSubmit={e => onSubmit(e)}> <div className="form-group"> <label htmlFor="exampleInputPassword1">Password</label> <input type="password" className="form-control" id="exampleInputPassword1" placeholder="New Password" name="new_password" value={new_password} onChange={e => onChange(e)} minLength='6' required></input> </div> <div className="form-group"> <label htmlFor="exampleInputPassword1">Password</label> <input type="password" className="form-control" id="exampleInputPassword1" placeholder="Confirm New Password" name="re_new_password" value={re_new_password} onChange={e => onChange(e)} minLength='6' required></input> </div> <button type="submit" className="btn btn-primary">Reset Password</button> </form> </div> ); }; export default connect(null, { reset_password_confirm }) (ResetPasswordConfirm);
补充说明
- 确保你的路由配置中已经定义了对应的参数,比如:
<Route path="/reset-password/:uid/:token" element={<ResetPasswordConfirm />} /> - Hook的使用必须遵守React规则:只能在函数组件的顶层调用,不能在循环、条件判断或嵌套函数中调用。
内容的提问来源于stack exchange,提问作者xi chen
相关产品推荐
相关产品推荐

