将后端响应显示为对redux前端组件进行响应的消息



当用户输入错误密码时,我想将类似Incorrect password的错误消息显示为警告或toast。现在,我只在网络响应选项卡中看到这些消息,并想知道如何在前端显示响应。

这里的登录控制器功能:

loginUser: async (req, res, next) => {
try {
console.log("inside login controller")
const { email, password } = req.body
if (!email || !password) {
return res.status(400).json({ message: "Email and password are must" })
}
if (!validator.isEmail(email)) {
return res.status(400).json({ message: "Invalid email" })
}
const user = await User.findOne({ email })
if (!user) {
return res.status(404).json({ message: "This email does not exist" })
}
if (!user.confirmPassword(password)) {
// console.log("Password in login controller", password)
return res.status(401).json({ message: "Incorrect password" })
}
res.status(200).json({ user })
} catch (error) {
return next(error)
}
}

登录组件看起来像:

import React, { Component } from "react"
import validator from "validator"
import { loginUser } from "../actions/userActions"
import { connect } from "react-redux"
import { Link } from "react-router-dom"
import { toastError } from "../../utils/toastify"
class LoginForm extends Component {
constructor(props) {
super(props)
this.state = {
email: "",
password: "",
}
}
handleChange = (event) => {
const { name, value } = event.target
this.setState({
[name]: value,
})
}
handleSubmit = (event) => {
event.preventDefault()
const { email, password } = this.state
const loginData = {
email: this.state.email,
password: this.state.password,
}
if (!email || !password) {
return toastError("Email and password are must.")
}
if (password.length < 6) {
return toastError("Password must contain 6 characters.")
}
if (!validator.isEmail(email)) {
return toastError("Invalid email.")
}
this.props.dispatch(
loginUser(loginData, () => this.props.history.push("/"))
)
}
render() {
const isAuthInProgress = this.props.auth.isAuthInProgress
return (
<div>
<div className="field">
<p className="control has-icons-left has-icons-right">
<input
className="input"
onChange={this.handleChange}
name="email"
value={this.state.email}
type="email"
placeholder="Email"
/>
<span className="icon is-small is-left">
<i className="fas fa-envelope"></i>
</span>
</p>
</div>
<div className="field">
<p className="control has-icons-left">
<input
className="input"
onChange={this.handleChange}
name="password"
value={this.state.password}
type="password"
placeholder="Password"
/>
<span className="icon is-small is-left">
<i className="fas fa-lock"></i>
</span>
</p>
</div>
<div className="field">
<p className="control">
{isAuthInProgress ? (
<button className="button is-success is-loading">Login</button>
) : (
<button onClick={this.handleSubmit} className="button is-success">
Login
</button>
)}
</p>
</div>
<Link to="/forgot-password">
<p className="has-text-danger">Forgot password?</p>
</Link>
</div>
)
}
}
const mapStateToProps = (state) => {
return state
}
export default connect(mapStateToProps)(LoginForm)

登录操作

export const loginUser = (loginData, redirect) => {
return async (dispatch) => {
dispatch({ type: "AUTH_STARTS" })
try {
const res = await axios.post(`${baseUrl}/users/login`, loginData)
console.log(res.data)
dispatch({
type: "AUTH_SUCCESS",
data: { user: res.data.user }
})
localStorage.setItem("authToken", res.data.token)
redirect()
toastSuccess("You are now logged in!")
} catch (err) {
console.log
dispatch({
type: "AUTH_ERROR",
data: { err },
})
}
}
}

身份验证减少程序

const auth = (state = initialState, action) => {
switch (action.type) {
case "AUTH_STARTS":
return {
...state,
isAuthInProgress: true,
isAuthenticated: false,
authError: null,
}
case "AUTH_SUCCESS":
return {
...state,
isAuthInProgress: false,
authError: null,
isAuthenticated: true,
isIdentifyingToken: false,
user: action.data.user,
}
case "AUTH_ERROR":
return {
...state,
isAuthInProgress: false,
authError: action.data.error,
isAuthenticated: false,
user: {},
}

此外,是否需要像我在控制器和组件(如if (!email || !password)if (!validator.isEmail(email))(中所做的类似检查。还是应该只在后端?

由于您已经在还原器中有一个单独的状态来代替authError,它保存API错误响应,因此您可以通过在loginUser调度上使用回调函数来利用它。

handleSubmit = (event) => {
/* your-validation-code */
this.props.dispatch(loginUser(loginData, this.checkForLoginError()));
};
checkForLoginError = () => {
const authenticationError = this.props.auth.authError;
if (authenticationError === null) {
this.props.history.push("/");
} else {
return toastError(authenticationError);
}
};

最新更新