Next.js+Express邮箱验证:激活页路由参数获取失败
解决Next.js中邮箱激活页面的
TypeError: Cannot read property 'params' of undefined问题 你遇到的核心问题是混用了React Router和Next.js的路由系统——你的代码里用了React Router的match、Redirect和Link,但Next.js有自己独立的路由机制,不会给页面组件传递match props,这就是为什么你会看到Cannot read property 'params' of undefined的错误。
下面我会一步步帮你修正代码,实现正确的邮箱激活功能:
1. 替换React Router相关依赖
首先把React Router的导入换成Next.js自带的路由工具:
// 删掉这行 // import { Link, Redirect } from 'react-router-dom'; // 换成Next.js的Link和路由钩子 import Link from 'next/link'; import { useRouter } from 'next/router';
2. 正确获取动态路由参数
在Next.js的动态路由页面(比如[token].js)中,你需要用useRouter钩子来获取路由参数,而不是React Router的match.params:
import React, { useState, useEffect } from 'react' import { ToastContainer, toast } from 'react-toastify'; import axios from 'axios'; import jwt from 'jsonwebtoken'; import { authenticate, isAuth } from '../helpers/auth'; import Link from 'next/link'; import { useRouter } from 'next/router'; const Activate = () => { const router = useRouter(); // 初始化Next.js路由钩子 const [formData, setFormData] = useState({ email: '', token: '', show: true }); const { email, token, show } = formData; useEffect(() => { // 从router.query中获取token参数 const urlToken = router.query.token; if (urlToken) { try { const { email } = jwt.decode(urlToken); setFormData(prev => ({ ...prev, email, token: urlToken })); // 调用后端激活接口完成入库逻辑 handleActivate(urlToken); } catch (err) { toast.error('无效的激活链接,请检查邮箱内容'); } } }, [router.query.token]); // 监听token参数变化 // 新增激活请求逻辑,对接Express后端 const handleActivate = async (token) => { try { const res = await axios.post('/api/user/activate', { token }); toast.success(res.data.message); // 激活成功后自动跳转登录页 setTimeout(() => router.push('/login'), 2000); } catch (err) { toast.error(err.response?.data?.message || '激活失败,请稍后重试'); } }; // 已登录用户直接跳转首页,用router.push代替React Router的Redirect useEffect(() => { if (isAuth()) { router.push('/'); } }, []); return ( <> <ToastContainer /> <div className="auth-container"> <h1>激活你的账户</h1> {!token ? ( <p>正在验证激活链接...</p> ) : ( <p>正在激活账户:<em>{email}</em></p> )} <p>还没有账户?<Link href="/register"><a>立即注册</a></Link></p> </div> </> ) }; export default Activate;
3. 关键修正点说明
- 路由参数获取:Next.js通过
router.query来获取动态路由参数,而非React Router的match.params - 页面跳转:用
router.push()或router.replace()代替React Router的Redirect组件,符合Next.js路由规范 - 错误处理:增加jwt解码的
try/catch,避免无效token导致的页面崩溃 - 激活逻辑:补充了对接后端的请求代码,完成用户入库MongoDB的核心流程
4. 关于你的HOC私有路由
你的HOC代码是符合Next.js规范的,无需修改,只需在需要保护的页面中正确引入使用即可,例如:
// 示例:在用户仪表盘页面使用私有路由HOC import withAuth from '../../hoc/withAuth'; const Dashboard = ({ userAuth }) => { return <h1>欢迎回来,{userAuth.auth.isAdmin ? '管理员' : '用户'}</h1>; }; export default withAuth(Dashboard);
这样修改后,你的邮箱激活页面就能正常获取token参数,完成解码和后端交互的逻辑,不会再出现之前的undefined错误了。
内容的提问来源于stack exchange,提问作者EL-Mehdi Loukach
相关产品推荐
相关产品推荐

