[英]REACT JS: Unhandled Rejection (TypeError): Cannot read property 'data' of undefined
I was requesting for some help with the below error which is occurring in my React js Frontend in my Login Form after Submitting required details inside the form.在表单中提交所需的详细信息后,我正在请求有关以下错误的帮助,该错误发生在我的登录表单中的 React js 前端。
Unhandled Rejection (TypeError): Cannot read property 'data' of undefined未处理的拒绝(TypeError):无法读取未定义的属性“数据”
This is a screenshot Chrome of the error displayed on Chrome and the Chrome console这是 Chrome 和 Chrome 控制台上显示的错误的屏幕截图
It occured when I was trying to login after clicking the Submit button of my Login form but on my backend since am working on a MERN App it actually submits the data correctly and verifies it and I get a 200 Success message , the screenshot to my VS Code Console.它发生在我单击登录表单的提交按钮后尝试登录但在我的后端,因为我正在使用MERN 应用程序,它实际上正确提交数据并验证它,我收到200 Success 消息,我的 VS 的屏幕截图代码控制台。
What I was thinking the error mainly was occuring on my React Frontend and my backened was running smoothly, I tried looking about the error on the Internet and could not get the specific fix for it but it had to do with a try and catch to fix it but did not workout successfully on my end.我在想这个错误主要发生在我的React 前端并且我的后端运行顺利,我尝试在 Internet 上查找错误并且无法获得具体的修复,但它与try and catch修复有关它但我没有成功锻炼。
The code below is the specific code on my Login.js which is bringing the error.下面的代码是我的 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');
The Full Code for my Login.js file is as below;我的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
These are the controllers on my backend I was using for my Login.js frontend form called loginController but for the Backend seems to be alright since I got a 200 Success message on the VS Code console as shown in the images above这些是我用于我的Login.js 前端表单loginController的后端控制器,但后端似乎没问题,因为我在VS Code 控制台上收到了200 Success 消息,如上图所示
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
}
})
})
}
}
After adding console.log(err)
to my code this is the Output that occured in the Chrome Console.将console.log(err)
添加到我的代码后,这是 Chrome 控制台中出现的 Output。 The Error message displayed read显示的错误消息已读
TypeError Cannot read property 'push' of undefined TypeError 无法读取未定义的属性“推送”
And also here is a Screenshot below to the Chrome console.log output下面是Chrome 控制台的屏幕截图。日志 output
At first, you need to check the data in your err
object.首先,您需要检查您的err
object 中的数据。
In the success case, you're checking res.data.user.username
Just try to look inside err
before you are calling err.response.data.errors
, obviously that err.response
is undefined.在成功的情况下,您正在检查res.data.user.username
只需在调用err.response.data.errors
之前尝试查看err
内部,显然err.response
是未定义的。
Before passing your error message in toast, Check that by doing console.在 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);
}
});
This is not directly an answer and anyone is free to correct me since I am not a pro at React.js but because I managed to get a few things working thought I should post now my error came from the following;这不是一个直接的答案,任何人都可以自由地纠正我,因为我不是 React.js 的专业人士,但因为我设法让一些事情正常工作,我认为我现在应该发布我的错误来自以下内容;
First of all for this am using React Router v6 in my code首先,我在我的代码中使用React Router v6
First in the Routes I needed to have added these two paths;首先在路线中,我需要添加这两条路径;
{ path: '/private', element: <PrivateRoute /> },
{ path: '/admin', element: <AdminRoute /> },
And second of all was to convert history.push since its no longer supported in React.其次是转换history.push ,因为 React 不再支持它。
This means I had to convert history.push to useNavigate using navigate in the following way;这意味着我必须通过以下方式使用导航将 history.push 转换为 useNavigate;
?history.push('/admin')
:history.push('/private');
The converted code is as below not forgetting to import useNavigate like import { useNavigate } from 'react-router-dom';
转换后的代码如下,不要忘记 import useNavigate like import { useNavigate } from 'react-router-dom';
and then calling it as const navigate = useNavigate();
然后将其称为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!`);
})
As you can see from my image Screenshot my error is cleared and the Chrome console is also clear and if you can Zoom in on the URL BAR you can notice the routes changed successfully from /login to /private ;正如您从我的图像屏幕截图中看到的那样,我的错误已清除,Chrome 控制台也很清晰,如果您可以放大URL BAR ,您会注意到路线已成功从/login更改为/private ;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.