首页 > 解决方案 > React js TypeError:无法读取未定义的属性“参数”

问题描述

我正在使用“react-router”:“^6.0.0-beta.0”,在我的Activate.js 文件中,我在 Chrome 上不断收到错误,如下所示

TypeError:无法读取未定义的属性“参数”

这是我的 Activate.js 的代码示例,我正在使用带有反应挂钩的功能组件,现在此代码的工作原理是,当您注册并单击电子邮件激活链接时向您发送电子邮件时,它会将您重定向到单击一个按钮以激活帐户,这正是我得到“无法读取未定义的属性'参数'” 的地方 下面的代码正是出现错误的地方。

useEffect(() => {
/*   get token from params like /active/token
then decode this token and get name*/
let token = match.params.token; //Error is occuring Here
let name = jwt.decode(token);

if (token) {
  setFormData({ ...formData, name, token });
}

整个Activate.js文件的完整代码示例如下

    /* eslint-disable no-unused-vars */
import React, { useState, useEffect } from 'react';
import authSvg from '../assets/welcome.svg';
import { ToastContainer, toast } from 'react-toastify';
import axios from 'axios';
import jwt from 'jsonwebtoken';
import { authenticate, isAuth } from '../helpers/auth';
// import { Link, Redirect } from 'react-router-dom';
import { Link as RouterLink, useNavigate } from 'react-router-dom';

const Activate = ({ match }) => {
  const [formData, setFormData] = useState({
    name: '',
    token: '',
    show: true
  });

  useEffect(() => {
    /*   get token from params like /active/token
    then decode this token and get name*/
    let token = match.params.token; //Error is occuring Here
    let name = jwt.decode(token);

    if (token) {
      setFormData({ ...formData, name, token });
    }

    console.log(token, name);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  const { name, show, token } = formData;

  const handleSubmit = e => {
    e.preventDefault();

    axios
      .post(`${process.env.REACT_APP_API_URL}/activation`, {
        token
      })
      .then(res => {
        setFormData({
          ...formData,
          show: false
        });
        toast.success(res.data.message);
      })
      .catch(err => {      
        toast.error(err.response.data.errors);
      });
  };

  const navigate = useNavigate();

  return (
    <div className='min-h-screen bg-gray-100 text-gray-900 flex justify-center'>
      {isAuth() ? <navigate to='/app/dashboard' /> : null}
      <ToastContainer />
      <div className='max-w-screen-xl m-0 sm:m-20 bg-white shadow sm:rounded-lg flex justify-center flex-1'>
        <div className='lg:w-1/2 xl:w-5/12 p-6 sm:p-12'>
          <div className='mt-12 flex flex-col items-center'>
            <h1 className='text-2xl xl:text-3xl font-extrabold'>
              Welcome {name}
            </h1>

            <form
              className='w-full flex-1 mt-8 text-indigo-500'
              onSubmit={handleSubmit}
            >
              <div className='mx-auto max-w-xs relative '>
                <button
                  type='submit'
                  className='mt-5 tracking-wide font-semibold bg-indigo-500 text-gray-100 w-full py-4 rounded-lg hover:bg-indigo-700 transition-all duration-300 ease-in-out flex items-center justify-center focus:shadow-outline focus:outline-none'
                >
                  <i className='fas fa-user-plus fa 1x w-6  -ml-2' />
                  <span className='ml-3'>Activate your Account</span>
                </button>
              </div>
              <div className='my-12 border-b text-center'>
                <div className='leading-none px-2 inline-block text-sm text-gray-600 tracking-wide font-medium bg-white transform translate-y-1/2'>
                  Or sign up again
                </div>
              </div>
              <div className='flex flex-col items-center'>
                <a
                  className='w-full max-w-xs font-bold shadow-sm rounded-lg py-3
           bg-indigo-100 text-gray-800 flex items-center justify-center transition-all duration-300 ease-in-out focus:outline-none hover:shadow focus:shadow-sm focus:shadow-outline mt-5'
                  href='/register'
                  target='_self'
                >
                  <i className='fas fa-sign-in-alt fa 1x w-6  -ml-2 text-indigo-500' />
                  <span className='ml-4'>Sign Up</span>
                </a>
              </div>
            </form>
          </div>
        </div>
        <div className='flex-1 bg-indigo-100 text-center hidden lg:flex'>
          <div
            className='m-12 xl:m-16 w-full bg-contain bg-center bg-no-repeat'
            style={{ backgroundImage: `url(${authSvg})` }}
          ></div>
        </div>
      </div>
      ;
    </div>
  );
};

export default Activate;

下面是如何路由我的 Activate.js 文件的代码

import { Navigate } from 'react-router-dom';
import DashboardLayout from 'src/components/DashboardLayout';
import MainLayout from 'src/components/MainLayout';
import Account from 'src/pages/Account';
import CustomerList from 'src/pages/CustomerList';
import AssistantList from 'src/pages/AssistantList';
import MarketList from 'src/pages/MarketList';
import Dashboard from 'src/pages/Dashboard';
import Login from 'src/pages/Login';
import NotFound from 'src/pages/NotFound';
import ProductList from 'src/pages/ProductList';
import Register from 'src/pages/Register';
import Settings from 'src/pages/Settings';
import Activate from 'src/pages/Activate';

const routes = [
  {
    path: 'app',
    element: <DashboardLayout />,
    children: [
      { path: 'account', element: <Account /> },
      { path: 'assistants', element: <AssistantList /> },
      { path: 'customers', element: <CustomerList /> },
      { path: 'dashboard', element: <Dashboard /> },
      { path: 'markets', element: <MarketList /> },
      { path: 'products', element: <ProductList /> },
      { path: 'settings', element: <Settings /> },
      { path: '*', element: <Navigate to="/404" /> }
    ]
  },
  {
    path: '/',
    element: <MainLayout />,
    children: [
      { path: 'login', element: <Login /> },
      { path: 'register', element: <Register /> },
      { path: '404', element: <NotFound /> },
      { path: '/', element: <Navigate to="/app/dashboard" /> },
      { path: '*', element: <Navigate to="/404" /> },
      { path: '/users/activate/:token', element: <Activate /> }, //This the route am using to route for my activate.js file
    ]
  }
];

export default routes;

只是补充一下,我正在关注一个教程,例如,这是他用来在他的 activate.js 文件中路由道具的一个例子,这就是我认为我的代码中的问题无法捕获尽管在他的教程中他使用的是更高版本的 react 而不是我在这种情况下使用的“react-router”:“^6.0.0-beta.0”,但我可能会遇到的道具,但下面是一个示例他的代码。

ReactDOM.render((
    <BrowserRouter>
        <App />
        <Route path='/' exact render={props => <App {...props} />}/>
        <Route path='/register' exact render={props => <Register {...props} />}/>
        <Route path='/users/activate/:token' exact render={props => <Activate {...props} />}/>
    </BrowserRouter> 
), document.getElementById('root'));

图像是 Chrome 浏览器上显示的错误。

标签: node.jsreactjsreact-hooksuse-effectmern

解决方案


您可以尝试使用useParams挂钩:

import { Link as RouterLink, useNavigate, useParams } from 'react-router-dom';

const Activate = () => {
  const [formData, setFormData] = useState({
    name: '',
    token: '',
    show: true
  });
  const {token} = useParams();

  useEffect(() => {
    let name = jwt.decode(token);

    if (token) {
      setFormData({ ...formData, name, token });
    }
    console.log(token, name);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  ...

推荐阅读