因此,正如标题所示,我正在尝试查找用户是否存在。以下是我迄今为止所做的工作。我在处理handleSubmit
函数中的验证时遇到问题。
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"
class RegistrationForm extends Component {
constructor(props) {
super(props)
this.state = {
username: "",
email: "",
password: "",
}
}
handleChange = (event) => {
const { name, value } = event.target
this.setState({
[name]: value,
})
}
handleSubmit = (event) => {
event.preventDefault()
const { username, email, password } = this.state
const registrationData = this.state
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.")
}
this.props.dispatch(checkValidUser(email)) // how do i properly handle validations here
this.props.dispatch(
registerUser(registrationData, () => this.props.history.push("/login"))
)
}
render() {
const isRegistrationInProgress = this.props.registration.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 state
}
export default connect(mapStateToProps)(RegistrationForm)
checkValidUser操作创建者
export const checkValidUser = (email) => {
return async dispatch => {
dispatch({ type: "CHECK_VALID_USER_STARTS" })
try {
const res = await axios.get(`${baseUrl}/users/checkValidUser/${email}`)
dispatch({
type: "CHECK_VALID_USER_SUCCESS",
data: { message: res.data.message }
})
} catch (err) {
dispatch({
type: "CHECK_VALID_USER_ERROR",
data: { error: "Something went wrong" },
})
}
}
}
路由-router.get("/checkValidUser/:email", usersController.checkValidUser)
checkValidUser控制器功能
checkValidUser: async (req, res, next) => {
const { email } = req.params
try {
const user = await User.findOne({ email })
if (!user) {
return res.status(404).json({ error: "No user found" })
}
return res.status(200).json({ message: "User already exists" })
} catch (error) {
return next(error)
}
}
配准减少器
const initialState = {
isRegistrationInProgress: false,
isRegistered: false,
registrationError: null,
user: {},
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,
isRegistrationInProgress: true,
}
case "CHECK_VALID_USER_SUCCESS":
return {
...state,
isRegistrationInProgress: false,
message: action.data.message,
}
case "CHECK_VALID_USER_ERROR":
return {
...state,
registrationError: action.data.error,
}
default:
return state
}
}
export default registration
如有任何帮助,我们将不胜感激。谢谢
checkValidUser
不是和password.length < 6
一样的验证类型吗?我只想在验证中同步调用它。在后端,如果可能的话,我会更改状态代码。如果用户已经存在,那就是有问题的情况,所以419(冲突(比200更适合。如果没有使用电子邮件,则应该返回200或204。有了这个,前端检查非常容易:
export const checkValidUser = async (email) => {
try {
const res = await axios.get(`${baseUrl}/users/checkValidUser/${email}`)
return true
} catch (err) {
return false
}
}
和在handleSubmit
中
handleSubmit = async (event) => {
event.preventDefault()
const { username, email, password } = this.state
const registrationData = this.state
...
if(!(await checkValidUser(email))) {
return toastError("...")
}
this.props.dispatch(
registerUser(registrationData, () => this.props.history.push("/login"))
)
}
这样,您就不需要CHECK_VALID_USER
状态,但可能需要添加某种VALIDATION_IN_PROGRESS
操作来在页面上显示某个指示符,即后台进程正在运行,就像微调器一样。这可以通过一个简单的try/finally
包装器来实现。因此,无论在哪种情况下退出验证,验证进度状态都将重置。
handleSubmit = async (event) => {
event.preventDefault()
const { username, email, password } = this.state
const registrationData = this.state
try {
this.props.dispatch(setValidationProgress(true)
...
if(!(await checkValidUser(email))) {
return toastError("...")
}
} finally {
this.props.dispatch(setValidationProgress(false)
}
this.props.dispatch(
registerUser(registrationData, () => this.props.history.push("/login"))
)
}