【发布时间】:2020-04-29 11:23:58
【问题描述】:
当前状态:未解决
我只是想显示一条错误消息以查看用户电子邮件是否已存在。为此,我有 checkValidUser 函数返回响应。现在,我在RegistrationForm 组件中以message 的身份访问这些响应。
现在我可以在组件中控制消息,如下所示。
所以,流程是这样的:
当用户输入电子邮件时,如果电子邮件已经存在于数据库中,则应该显示一个 toastError 说“用户已经存在”。如果数据库中不存在电子邮件,则 toastSuccess 应显示“您已成功注册”,同时重定向到登录页面。
我不知道如何做到这一点。
RegistrationForm.js
import React, { Component } from "react";
import { registerUser, checkValidUser } from "../actions/userActions";
import { connect } from "react-redux";
import validator from "validator";
import { Link } from "react-router-dom";
import { toastError, toastInfo, toastSuccess } from "../../utils/toastify";
class RegistrationForm extends Component {
constructor(props) {
super(props);
this.state = {
username: "",
email: "",
password: "",
};
}
handleChange = (event) => {
const { name, value } = event.target;
this.setState({
[name]: value,
});
};
componentDidUpdate(prevProps) {
console.log(" inside componentDidUpdate");
console.log("cdu", "prevProp=>", prevProps.message, "newProp=>", this.props.message);
}
handleSubmit = async (event) => {
event.preventDefault();
const { username, email, password } = this.state;
const registrationData = {
username: this.state.username,
email: this.state.email,
password: this.state.password,
};
if (!username || !email || !password) {
return toastError("Credentials should not be empty");
}
if (username.length < 6) {
return toastError("Username should be greater than 6 characters.");
}
if (!validator.isEmail(email)) {
return toastError("Invalid email.");
}
if (password.length < 6) {
return toastError("Password must contain 6 characters.");
}
await this.props.dispatch(checkValidUser(email));
const message = this.props.message;
console.log("message in component=>", message)
}
render() {
console.log("render");
const isRegistrationInProgress = this.props.isRegistrationInProgress;
return (
<div>
<div className="field">
<p className="control has-icons-left has-icons-right">
<input
onChange={this.handleChange}
name="username"
value={this.state.username}
className="input"
type="text"
placeholder="Username"
/>
<span className="icon is-small is-left">
<i className="fas fa-user"></i>
</span>
</p>
</div>
<div className="field">
<p className="control has-icons-left has-icons-right">
<input
onChange={this.handleChange}
name="email"
value={this.state.email}
className="input"
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
onChange={this.handleChange}
name="password"
value={this.state.password}
className="input"
type="password"
placeholder="Password"
/>
<span className="icon is-small is-left">
<i className="fas fa-lock"></i>
</span>
</p>
</div>
<div className="field">
<div className="control">
{isRegistrationInProgress ? (
<button className="button is-success is-loading">Sign Up</button>
) : (
<button onClick={this.handleSubmit} className="button is-success">
Sign up
</button>
)}
<Link to="/login">
<p className="has-text-danger">
Already have an account? Sign In
</p>
</Link>
</div>
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
isRegistrationInProgress: state.registration.isRegistrationInProgress,
message: state.registration.message,
};
};
export default connect(mapStateToProps)(RegistrationForm);
注册用户操作
export const registerUser = (registrationData, redirect) => {
console.log("registrationData", registrationData)
return async (dispatch) => {
dispatch({ type: "REGISTRATION_STARTS" })
try {
const res = await axios.post(
`${baseUrl}/users/register`,
registrationData
)
dispatch({
type: "REGISTRATION_SUCCESS",
data: { user: res.data.user },
})
toastSuccess("Successfully registered")
redirect()
} catch (err) {
dispatch({
type: "REGISTRATION_ERROR",
data: { error: err },
})
}
}
}
checkValidUser控制器功能
checkValidUser: async (req, res, next) => {
console.log("inside check valid user controller")
const { email } = req.params
console.log(email)
try {
const user = await User.findOne({ email })
if (user) {
return res.status(200).json({ message: "User already exists" })
} else {
return res.json({ message: "User does not exists" })
}
} catch (error) {
return next(error)
}
}
registerUser控制器功能:
registerUser: async (req, res, next) => {
try {
var { username, email, password } = req.body
if (password) {
const salt = bcrypt.genSaltSync(10)
password = bcrypt.hashSync(password, salt)
}
if (!username || !email || !password) {
return res
.status(400)
.json({ message: "Username, email and password are must" })
}
if (!validator.isEmail(email)) {
return res.status(400).json({ message: "Invaid email" })
}
if (password.length < 6) {
return res
.status(400)
.json({ message: "Password should be of at least 6 characters" })
}
const user = await User.create({ username, email, password })
if (!user) {
return res.status(404).json({ error: "No user found " })
}
return res.status(200).json({ user })
} catch (error) {
return next(error)
}
}
注册减少器
const initialState = {
isRegistrationInProgress: false,
isRegistered: false,
registrationError: null,
user: {},
isValidating: false,
isValidated: false,
validationError: null,
message: "",
}
const registration = (state = initialState, action) => {
switch (action.type) {
case "REGISTRATION_STARTS":
return {
...state,
isRegistrationInProgress: true,
registrationError: null,
}
case "REGISTRATION_SUCCESS":
return {
...state,
isRegistrationInProgress: false,
registrationError: null,
isRegistered: true,
user: action.data,
}
case "REGISTRATION_ERROR":
return {
...state,
isRegistrationInProgress: false,
registrationError: action.data.error,
isRegistered: false,
user: {},
}
case "CHECK_VALID_USER_STARTS":
return {
...state,
isValidating: true,
isValidated: false,
validationError: null,
}
case "CHECK_VALID_USER_SUCCESS":
return {
...state,
isValidating: false,
isValidated: true,
message: action.data.message,
}
case "CHECK_VALID_USER_ERROR":
return {
...state,
validationError: action.data.error,
}
default:
return state
}
}
export default registration
checkValidUser 操作
export const checkValidUser = (email) => {
return async (dispatch) => {
dispatch({ type: "CHECK_VALID_USER_STARTS" })
try {
const res = await axios.get(`${baseUrl}/users/checkValidUser/${email}`)
console.log("message in action=>", res.data)
dispatch({
type: "CHECK_VALID_USER_SUCCESS",
data: { message: res.data.message },
})
} catch (err) {
dispatch({
type: "CHECK_VALID_USER_ERROR",
data: { error: "Something went wrong" },
})
}
}
}
【问题讨论】:
-
能否将完整链接添加到 github 项目。这样,可视化会更容易。我正在查看您的调度程序在哪里调用后端 API 方法。
-
你不应该打电话给 registerUser 吗?
-
@tksilicon 是的,但在此之前,我必须检查电子邮件是否有效。所以,
checkValidUser就在那里。是的,我需要打电话给registerUser。 -
我很困惑是否在 componentDidUpdate 中显示错误消息并从那里重定向。
-
你的减速机在哪里?调用控制器的 checkValidUser 操作在哪里?您两次发布了 registerUser。
标签: javascript reactjs express redux react-redux