【问题标题】:Displaying error message and redirecting from the component显示错误消息并从组件重定向
【发布时间】: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


【解决方案1】:

在您的 mapStateToProps 中,因为您的组件在发送电子邮件操作时需要 isValidated 当前状态:

const mapStateToProps = (state) => {
          return {
            isRegistrationInProgress: state.registration.isRegistrationInProgress,
            message: state.registration.message,
           isValidated: state.checkValidUser.isValidated
          };
        };

您应该在发送您的 checkValidUser 操作后检查您的响应消息。因为如果调用成功,响应将是 200,但这并不意味着验证是否存在电子邮件。

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)

      if(res.data.messsage="User does not exists"){//you can just return 
          dispatch({                                 // success or failed
        type: "CHECK_VALID_USER_SUCCESS",
        data: { message: res.data.message },
      })
       toastSuccess("Success");
      redirect();
      }else{
       toastError("Email exists")
     }

    } catch (err) {
      dispatch({
        type: "CHECK_VALID_USER_ERROR",
        data: { error: "Something went wrong" },
      })
    }
  }
}

【讨论】:

  • 那么,后端响应如何,注册成功后重定向?
  • Idk 但this.props.isValidated 始终为真,无论输入错误或正确的电子邮件地址。
  • 您应该在发送您的 checkvalidemail 操作后检查您的回复消息。因为如果调用成功,响应将是 200,但这并不意味着经过验证的电子邮件是否存在。那将是您用来发送成功或失败的信息。那么这也是你应该使用的重定向()
猜你喜欢
  • 1970-01-01
  • 2022-07-18
  • 1970-01-01
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
  • 2019-01-06
  • 2014-12-31
  • 2018-07-24
相关资源
最近更新 更多