【问题标题】:REACT JS: Unhandled Rejection (TypeError): Cannot read property 'data' of undefinedREACT JS:未处理的拒绝(TypeError):无法读取未定义的属性“数据”
【发布时间】:2021-08-29 20:32:45
【问题描述】:

在表单中提交所需的详细信息后,我正在请求一些帮助,以解决在我的登录表单中的 React js 前端中发生的以下错误。

未处理的拒绝(TypeError):无法读取未定义的属性“数据”

这是在 Chrome 和 Chrome 控制台987654321@上显示的错误的 Chrome 截图

当我点击登录表单的提交按钮后尝试登录时发生这种情况,但在我的后端,因为我正在使用 MERN 应用程序,它实际上提交了数据正确并验证它,我收到 200 成功消息,这是我的 VS 代码控制台的屏幕截图。

我认为错误主要发生在我的 React 前端 并且我的后端运行顺利,我尝试在 Internet 上查找错误并无法获得具体的修复,但它必须通过 try and catch 来修复它,但我没有成功锻炼。

下面的代码是我的 Login.js 上导致错误的特定代码。

  241 |           password1: '',
  242 |           textChange: 'Sign In'
  243 |         });
> 244 |         toast.error(err.response.data.errors); //This is the line where React is complaining of the error
      | ^  245 |       });
  246 | } else {
  247 |   toast.error('Please fill all fields');

我的 Login.js 文件的完整代码如下;

import React, { useState } from 'react'
import authSvg from '../assets/login.svg'
import { ToastContainer, toast } from 'react-toastify';
import { authenticate, isAuth } from '../helpers/auth';
import axios from 'axios';
// import { Redirect } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';


const Login = ({ history }) => {
    const [formData, setFormData] = useState({
        email: '',
        password1: '',
        textChange: 'Sign In'
    })

    const {email, password1, textChange } = formData
    // Handle change inputs
    const handleChange = text => e => {
        // console.log(username, email, phone, firstName, lastName, password)
        setFormData({...formData, [text]: e.target.value})
    }

    // Submit data to backend
    const handleSubmit = e => {
        console.log(process.env.REACT_APP_API_URL);
        e.preventDefault()
        if (email && password1){
            setFormData({ ...formData, textChange: 'Submitting' });
            axios.post(`${process.env.REACT_APP_API_URL}/login`, {
                email,
                password: password1
            }).then(res => {
                authenticate(res, () => {
                    setFormData({
                        ...formData,
                        email: '',
                        password1: '',
                        textChange: 'Submitted'
                    })
                    console.log(res.data)
                })
                  // if authenticate but not admin redirect to / private
                  // if admin redirect to /admin
              isAuth() && isAuth().role === 'admin'
                  ?history.push('/')
                  :history.push('/register'); //Here for now am testing the routing with the available routes I have at the moment
              toast.success(`Hey ${res.data.user.username}, Welcome back!`);
                  toast.success(`Hey ${res.data.user.username}, Welcome back!`);
                })
                .catch(err => {
                  setFormData({
                    ...formData,
                    email: '',
                    password1: '',
                    textChange: 'Sign In'
                  });
                  toast.error(err.response.data.errors); //This is the line where I get the React **undefined** Error
                });
          } else {
            toast.error('Please fill all fields');
          }
        };

    const navigate = useNavigate();

    return (
        <div className='min-h-screen bg-gray-100 text-gray-900 flex justify-center'>
          {/* {isAuth() ? <Redirect to='/' /> : null} */}
        {isAuth() ? <navigate to='/' /> : 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'>
                Sign In for Ntuma
              </h1>
  
              <form
                className='w-full flex-1 mt-8 text-indigo-500'
                onSubmit={handleSubmit}
              >
                <div className='mx-auto max-w-xs relative '>
                  <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 mt-5'
                    type='email'
                    placeholder='Email'
                    onChange={handleChange('email')}
                    value={email}
                  />
                  <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 mt-5'
                    type='password'
                    placeholder='Password'
                    onChange={handleChange('password1')}
                    value={password1}
                  />
                  <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'>{textChange}</span>
                  </button>
                  <a
                    href='/users/password/forget'
                    className='no-underline hover:underline text-indigo-500 text-md text-right absolute right-0  mt-2'
                >
                  Forget password?
                </a>
                </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
                  </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'>Log In</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 Login

这些是我的后端上的 控制器 似乎没问题,因为我在 VS Code 控制台 上收到了 200 条成功消息,如上图所示

exports.loginController = (req, res) => {
  const { email, password } = req.body
  const errors = validationResult(req)

  // Validation to req.body we will create custom validation in seconds
  if (!errors.isEmpty()) {
    const firstError = errors.array().map((error) => error.msg)[0];
    return res.status(422).json({
      errors: firstError,
    });
  } else {
    // Check if user exist
    RegistersignUp.findOne({
      email
    }).exec((err, user) => {
      if (err || !user) {
        return res.status(400).json({
          errors: 'User with that email does not exist. Please Signup'
        });
      }
    
      // Authenticate
      if (!user.authenticate(password)) {
        return res.status(400).json({
          errors: 'Email and password do not match'
        })
      }

      // Generate Token
      const token = jwt.sign(
        {
          _id: user._id
        }, process.env.JWT_SECRET,
        {
          expiresIn: '7d' // Token valid in 7 day you can set remember in front and set it for 30 days
        }
      )
      const {
        _id,
        username,
        email,
        role,
      } = user
      return res.json({
        token,
        user: {
          _id,
          username,
          email,
          role
        }
      })
    })
  }
}

在我的代码中添加 console.log(err) 后,这是 Chrome 控制台中出现的输出。 显示的错误消息已读

TypeError 无法读取未定义的属性“push”

下面是 Chrome console.log 输出的屏幕截图

【问题讨论】:

  • 使用console.log(err) 这样你就可以看到它返回了什么。
  • 我在 toast 的顶部添加了 console.log(err),这是错误我得到屏幕截图链接imgur.com/undefined 安慰后的错误消息是“TypeError: Cannot read property 'push' of undefined "
  • 早上好对不起,这个截图有错误,认为是网络,但我仍然上传了图片这是重新发送的截图,请imgur.com/PxfIN2F

标签: javascript reactjs axios react-hooks mern


【解决方案1】:

首先,您需要检查您的err 对象中的数据。

在成功的情况下,您正在检查res.data.user.username 在调用err.response.data.errors 之前尝试查看err 内部,显然err.response 是未定义的。

【讨论】:

  • 我添加了一个 console.log(err),这是显示“TypeError Cannot read property 'push' of undefined”的错误消息,我想这就是你希望我对 console.log 正确的。
  • 早上好对不起,这个截图有错误,认为是网络,但我仍然上传了图片这是重新发送的截图,请 imgur.com/PxfIN2F
【解决方案2】:

在 toast 中传递错误消息之前,请通过控制台检查。

.catch((error) => {
    if (error.response) {
      // Request made and server responded
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // The request was made but no response was received
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
});

【讨论】:

  • 我收到了如下屏幕截图中显示的错误imgur.com/undefined 我删除了我的 .catch 并在我的代码末尾用你的 .catch 替换了这就是我得到的错误消息“错误无法读取属性'push' of undefined"
  • 早上好对不起,这个截图有错误,认为是网络,但我仍然上传了图片这是重新发送的截图,请 imgur.com/PxfIN2F
【解决方案3】:

这是不直接的答案,任何人都可以免费纠正我,因为我不是 React.js 的专业人士,但因为我设法让一些事情正常工作认为我现在应该发布我的错误来自以下内容;

首先,我在我的代码中使用 React Router v6

首先在路线中我需要添加这两条路径;

  { path: '/private', element: <PrivateRoute /> },
  { path: '/admin', element: <AdminRoute  /> },

其次是转换 history.push,因为 React 不再支持它。

这意味着我必须使用以下方式将 history.push 转换为 useNavigate;

      ?history.push('/admin')
      :history.push('/private');

转换后的代码如下不要忘记导入useNavigate like import { useNavigate } from 'react-router-dom'; 然后调用它为const navigate = useNavigate();

          // if authenticate but not admin redirect to / private
          // if admin redirect to /admin
          isAuth() && isAuth().role === 'admin'
              // ?history.push('/admin')
              // :history.push('/private');
              ?navigate('/admin')
              :navigate('/private')
          toast.success(`Hey ${res.data.user.username}, Welcome back!`);
        })

从我的图片截图中可以看到,我的 错误 已清除,Chrome 控制台也很清晰,如果您可以在 URL BAR放大 /strong> 你可以看到路由成功地从/login变成了/private

【讨论】:

  • 我还要感谢 cmets 部分的 evryone 提供的各种 错误处理 解决方案让我解决了这个错误,感谢所有帮助。
猜你喜欢
  • 1970-01-01
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-07
  • 2019-08-06
  • 2023-03-21
  • 2021-08-16
相关资源
最近更新 更多