You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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只能在组件顶层调用,不能在事件回调、嵌套函数中使用。

修改步骤:

  1. 移除组件参数中的match,因为v6不会再传递这个props
  2. 在组件顶层调用useParams()获取URL参数
  3. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:05:19