问题描述
我正在我的本地主机上开发一个(简单易用的)笔记 Web 应用程序(前端的端口 3000,后端的端口 5000)。我在实现用户登录功能时遇到了问题。我会尝试在这里提炼问题。
我的主要 App.jsx 组件有一个 LoginScreen.jsx 组件作为子组件,它在这里:
import { useState,useEffect } from 'react';
import { Link } from 'react-router-dom';
import AuthService from '../services/auth.js';
import './LoginScreen.css';
const LoginScreen = ({ history }) => {
const [email,setEmail] = useState('');
const [password,setPassword] = useState('');
const [error,setError] = useState('');
useEffect(() => {
if (localStorage.getItem('authToken')) history.push('/');
},[history]);
const loginHandler = async e => {
e.preventDefault();
try {
const data = { email,password };
AuthService.loginUser(data).then(response => {
localStorage.setItem('authToken',response.data.token);
});
history.push('/');
} catch (error) {
setError(error.response.data.error);
setTimeout(() => {
setError('');
},5000);
}
};
return (
<div className="login-screen">
<form
className="login-screen__form"
onSubmit={loginHandler}
autoComplete="off"
>
<h3 className="login-screen__title">Login</h3>
{error && <span className="error-message">{error}</span>}
<div className="form-group">
<label htmlFor="email">Email:</label>
<input
type="email"
required
id="email"
placeholder="enter email"
value={email}
onChange={e => setEmail(e.target.value)}
tabIndex={1}
/>
</div>
<div className="form-group">
<label htmlFor="password">
Password:{' '}
<Link
to="/forgotpassword"
className="login-screen__forgotpassword"
tabIndex={4}
>
Forgot Password?
</Link>
</label>
<input
type="password"
required
id="password"
placeholder="enter password"
value={password}
onChange={e => setPassword(e.target.value)}
tabIndex={2}
/>
</div>
<button type="submit" className="btn btn-primary" tabIndex={3}>
Login
</button>
<span className="login-screen__subtext">
Don't have an account? <Link to="/register">Register</Link>
</span>
</form>
</div>
);
};
export default LoginScreen;
当用户点击“登录”时,应该会触发 AuthService,如下所示:
import http from '../routing/http-auth.js';
class AuthService {
loginUser = data => http.post('/login',data);
registerUser = data => http.post('/register',data);
userForgotPassword = data => http.post('/forgotpassword',data);
userPasswordReset = data => http.put('/passwordreset/:resetToken',data);
}
export default new AuthService();
import axios from 'axios';
export default axios.create({
baseURL: 'http://localhost:5000/api/v1/auth',headers: {
'Content-type': 'application/json'
}
});
因此,请求被路由到后端,它在这里:
import express from 'express';
import AuthController from './auth.controller.js';
const router = express.Router();
router.route('/register').post(AuthController.register);
router.route('/login').post(AuthController.login);
router.route('/forgotpassword').post(AuthController.forgotPassword);
router.route('/passwordreset/:resetToken').put(AuthController.passwordReset);
export default router;
然后在这里:
static login = async (req,res,next) => {
const email = req.body.email;
const password = req.body.password;
if (!email || !password) {
return next(
new ErrorResponse('please provide an email and password',400)
);
}
try {
const user = await User.findOne({ email }).select('+password');
if (!user) return next(new ErrorResponse('invalid credentials',401));
const isMatch = await user.matchPasswords(password);
if (!isMatch) return next(new ErrorResponse('invalid credentials',401));
sendToken(user,200,res);
} catch (error) {
next(error);
}
};
这一切都适用于一个虚拟应用程序,但现在,它在我的笔记应用程序中不起作用。我收到错误:
Uncaught (in promise) TypeError: Cannot read property 'data' of undefined
at loginHandler (LoginScreen.jsx:27)
我怎样才能做到这一点?
解决方法
您的 TypeError: Cannot read property 'data' of undefined
表示您的代码试图从未定义(空,缺失)对象读取 .data
属性。
在第 27 行,您的代码执行 setError(error.response.data.error);
因此您的错误消息意味着 error
存在但 error.response
不存在。
将 console.log(error)
放在第 27 行之前(或设置断点),这样您就可以确保理解您捕获的 error
对象。
如果错误消息显示 TypeError: Cannot read property 'data' of an undefined object named error.response
,那就太好了。但事实并非如此,因此您必须自己进行推断。