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

Posted

技术标签:

【中文标题】REACT JS:TypeError:无法读取未定义的属性“参数”【英文标题】:REACT JS: TypeError: Cannot read property 'params' of undefined 【发布时间】:2021-08-30 00:46:48 【问题描述】:

我的 React 前端似乎有问题我正在处理我的 Reset.js 页面,但我一直收到错误

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

当我路由到 Reset.js 页面时就会发生这种情况,它的工作原理是当用户忘记他们的密码时,他们会按顺序发送一封电子邮件使用 jwt 重置他们的密码,当点击电子邮件上的链接时,它会将您转到 Reset.js 页面,您将在此处填写凭据以重置密码。

但是在到达路线的过程中,我收到了TypeError: Cannot read property 'params' of undefined 错误,这是受影响的 React js 代码行,如下所示。

  14 | const  password1, password2, textChange, token  = formData;
  15 | 
  16 | useEffect(() => 
> 17 |     let token = match.params.token // **Error is caused here Cannot read property 'params' of undefined**
     | ^  18 |     if(token) 
  19 |         setFormData(...formData, token,)
  20 |     

这也是 Chrome 错误的屏幕截图,方便查看。

这是我在 React 中的 Reset.js 页面的完整代码。

import React,  useState, useEffect  from 'react';
import authSvg from '../assets/reset.svg';
import  ToastContainer, toast  from 'react-toastify';
import axios from 'axios';

const Reset = (match) => 
  const [formData, setFormData] = useState(
      password1: '',
      password2: '',
      token: '',
    textChange: 'Submit'
  );
    // eslint-disable-next-line no-unused-vars
    const  password1, password2, textChange, token  = formData;
    
    useEffect(() => 
        let token = match.params.token // **Error is caused here Cannot read property 'params' of undefined**
        if(token) 
            setFormData(...formData, token,)
        
        
    // eslint-disable-next-line react-hooks/exhaustive-deps
    , [])
  const handleChange = text => e => 
    setFormData( ...formData, [text]: e.target.value );
  ;
    const handleSubmit = e => 
      console.log(password1, password2)
    e.preventDefault();
    if ((password1 === password2) && password1 && password2) 
      setFormData( ...formData, textChange: 'Submitting' );
      axios
        .put(`$process.env.REACT_APP_API_URL/password/reset`, 
            newPassword: password1,
            resetPasswordLink: token
        )
        .then(res => 
          console.log(res.data.message)
            setFormData(
              ...formData,
               password1: '',
              password2: ''
            );
            toast.success(res.data.message);
          
        )
        .catch(err => 
          toast.error('Something is wrong try again');
        );
     else 
      toast.error('Passwords don\'t matches');
    
  ;
  return (
    <div className='min-h-screen bg-gray-100 text-gray-900 flex justify-center'>
      <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'>
              Reset Your Password
            </h1>
            <div className='w-full flex-1 mt-8 text-indigo-500'>
              
              <form
                className='mx-auto max-w-xs relative '
                onSubmit=handleSubmit
              >
                <input
                  className='w-full px-8 py-4 rounded-lg font-medium bg-gray-100 border border-gray-200 placeholder-gray-500 text-sm focus:outline-none focus:border-gray-400 focus:bg-white'
                  type='password'
                  placeholder='password'
                  onChange=handleChange('password1')
                  value=password1
                  />
                  <input
                  className='w-full mt-5 px-8 py-4 rounded-lg font-medium bg-gray-100 border border-gray-200 placeholder-gray-500 text-sm focus:outline-none focus:border-gray-400 focus:bg-white'
                  type='password'
                  placeholder='Confirm password'
                  onChange=handleChange('password2')
                  value=password2
                />
                <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-sign-in-alt  w-6  -ml-2' />
                  <span className='ml-3'>Submit</span>
                </button>
              </form>
            </div>
          </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 Reset;

我还尝试通过添加 useParams 来修复它,虽然它似乎没有按计划进行锻炼,但这是我尝试进行的修复并且没有锻炼所以我决定寻求一些帮助,

这是我在下面尝试过的;

import  useParams  from 'react-router-dom';
import jwt from 'jsonwebtoken'; //added this because of the way I was using jwt.decode

    textChange: 'Submit'
  );
    // eslint-disable-next-line no-unused-vars
    const  password1, password2, textChange  = formData; //I removed token from here since we were calling it on line 21 in the params below
    // const  password1, password2, textChange, token  = formData; //this is the original code format and the one above is what I edited.
    
    const  token  = useParams();
    
    useEffect(() => 
        let password = jwt.decode(token); //added jwt.decode(token) here though at first it was match.params.token
        // let token = match.params.token
        if(token) 
            setFormData(...formData,password, token,) //added password here tho it wasnt supposed to be their as reference to the original code.
        
        
    // eslint-disable-next-line react-hooks/exhaustive-deps
    , [])

当我尝试上面的代码时显示的错误 useParamsChrome 控制台中读取。

PUT http://localhost:4000/api/password/reset 400(错误请求)

以下是错误,但以屏幕截图形式便于查看,但与上述相同。 然后下面是我用于 Reset.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';
import Forget from 'src/pages/Forget';
import Reset from 'src/pages/Reset'; //This is how I imported my Reset.js Page

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 /> ,
       path: '/users/password/forget', element: <Forget /> ,
       path: '/users/password/reset/:token', element: <Reset />  //Here is how I routed my reset.js page
    ]
  
];

export default routes;

【问题讨论】:

你也可以添加路由文件吗? @AmilaSenadheera 我已成功添加路线 @AJPHIL 您在使用 useParams 时遇到了哪个错误? @KOseare 现在我一直在试图弄清楚是否是网络问题,但似乎不是,所以这是我收到的错误的屏幕截图图像 imgur.com/lC1u59B 读取为 “加载资源失败:服务器响应状态为 400(错误请求)”,这是我更新的代码的屏幕截图图像 imgur.com/iAMUwv4 的链接 @KOseare 忽略第一个错误,这是现在遇到的错误 PUT localhost:4000/api/password/reset 400 (Bad Request) 我认为是第一个 错误是因为网络问题,但现在这是 正确的错误 我还 更新了上面的 问题,您可以使用它也供参考,我也没有更改代码它与我在上面最近的评论中发送它的方式相同。 【参考方案1】:

withRouter (https://reactrouter.com/web/api/withRouter) 包裹你的Reset 组件

【讨论】:

我添加了这一行 ( import withRouter from "react-router"; 然后将我的导出组件编辑为 "export default withRouter(Reset)" 但我收到一条错误消息,显示 "Attempted import error : 'withRouter' 不是从'react-router' 导出的。在 Chrome 浏览器中 应该从react-router-dom导入 我也添加了它,但它不起作用可能是因为我使用的是 react router v6 beta 这是一个截图,只是为了验证imgur.com/undefined @AJPHIL 我看不到截图

以上是关于REACT JS:TypeError:无法读取未定义的属性“参数”的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:无法读取 null 的属性(读取“推送”)react.js

TypeError:无法读取未定义的属性“当前”(使用 React.js)

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

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

TypeError:无法读取未定义的属性(读取“地图”),以及 React.js 中的多个 API 请求

React.JS TypeError:无法读取未定义的属性“编号”-(在 setState 内)