проверка при регистрации, если пользователь уже существует в базе данных с использованием реактивного редукса express - PullRequest
0 голосов
/ 19 апреля 2020

Итак, как следует из названия, я пытаюсь найти, существует ли пользователь или нет. Вот что я сделал до сих пор. У меня проблемы с обработкой проверки в функции 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

Любая помощь будет оценена. Спасибо.

1 Ответ

0 голосов
/ 19 апреля 2020

Разве checkValidUser не такой же тип проверки, как password.length < 6? Я бы просто назвал это синхронно внутри проверки. Со стороны сервера я бы изменил коды состояния, если это возможно. Если пользователь уже существует, это проблемный случай c, поэтому 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"))
    )
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...