如何在 mern 应用程序上显示错误消息

How to display error message on the mern app

我试图在用户尝试使用未注册用户登录时显示一条错误消息,但我无法在从后端发送的前端(reactjs)上收到该错误消息( nodejs, 表达, MongoDB).

我正在使用 redux 来处理 React 应用程序的状态。

用户登录表单提交代码:

   const onSubmit = (data) => {
    if (isLogin) {
      dispatch(signin(data, history));
    } else {
      dispatch(signup(data, history));
    }
  };

auth 的动作创建者

import * as api from "../api";

export const signin = (formData, history) => async (dispatch) => {
  try {
    // login the user
    const { data } = await api.signIn(formData);
    dispatch({ type: "AUTH", data });
    history.push("/");
  } catch (error) {
    console.log(error);
    dispatch({ type: "ERROR", data: error.response.data.message });
  }
};

export const signup = (formData, history) => async (dispatch) => {
  try {
    // sign up the user
    const { data } = await api.signUp(formData);
    dispatch({ type: "AUTH", data });
    history.push("/");
  } catch (error) {
    console.log(error);
  }
};

验证的减速器:

const authReducer = (state = { authData: null }, action) => {
  switch (action.type) {
    case "AUTH":
      localStorage.setItem("profile", JSON.stringify({ ...action?.data }));
      return { state, authData: action?.data };
    case "LOGOUT":
      localStorage.clear();
      return { state, authData: null };
    case "ERROR":
      return { state, authData: action?.data };
    default:
      return state;
  }
};

export default authReducer;

后台登录码

const signin = async (req, res) => {
  const { email, password } = req.body;
  try {
    const existingUser = await User.findOne({ email });
    if (!existingUser)
      return res.status(404).json({ message: "User doesn't exist." });

    const isPasswordCorrect = await bcrypt.compare(
      password,
      existingUser.password
    );
    if (!isPasswordCorrect)
      res.status(404).json({ message: "Invalid Credentials" });

    const token = jwt.sign(
      { email: existingUser.email, id: existingUser._id },
      "test",
      { expiresIn: "1h" }
    );
    res.status(200).json({ result: existingUser, token });
  } catch (error) {
    res.status(500).json({ message: "Something went wrong" });
  }
};

符号API

import axios from "axios";

const API = axios.create({
  baseURL: process.env.REACT_APP_BASE_URL,
});

export const signIn = (formData) => API.post("/user/signin", formData);
export const signUp = (formData) => API.post("/user/signup", formData);

任何人,请帮助我。

Postman中的错误响应截图:

据我了解,一切正常,实际上,前端没有发生任何错误。您必须检查“await api.signIn(formData);”的状态代码回复。如果它是 200,则表示一切正常,否则您必须检查响应中的消息以获取消息错误。由于在前端有抛出的错误被捕获。

我刚刚调试了这个问题。首先通过 npm install --save redux-devtools-extension 安装 redux-devtools-extension 然后在商店中应用它(index.js 文件,如下所示

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import App from "./App";
import { reducers } from "./reducers";
import { composeWithDevTools } from "redux-devtools-extension";

const middleware = [thunk];

const store = createStore(
  reducers,
  composeWithDevTools(applyMiddleware(...middleware))
);

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

现在您可以在任何地方使用错误消息,如下所示(您的 Auth.js 文件)

import React, { useState } from "react";
import { useSelector } from "react-redux";
import Input from "../utils/Input";
import Label from "../utils/Label";
import { useForm, FormProvider } from "react-hook-form";
import { GoogleLogin } from "react-google-login";
import { useDispatch } from "react-redux";
import { useHistory } from "react-router";
import { signin, signup } from "../../actions/auth";

const Auth = () => {
  const [isLogin, setIsLogin] = useState(true);
  const formMethods = useForm();
  const auth = useSelector((state) => state.auth);
  const { authData } = auth;
  const { handleSubmit } = formMethods;

  console.log(authData);
  const dispatch = useDispatch();
  const history = useHistory();

  const changeScreen = () => {
    setIsLogin(false);
    dispatch({ type: "LOGOUT" });
  };

  const onSubmit = (data) => {
    if (isLogin) {
      dispatch(signin(data, history));
    } else {
      dispatch(signup(data, history));
    }
  };

  const googleSuccess = async (res) => {
    const result = res?.profileObj;
    const token = res?.tokenId;

    try {
      dispatch({ type: "AUTH", data: { result, token } });
      history.push("/");
    } catch (error) {
      console.log(error);
    }
  };

  const googleFailure = (error) => {
    console.log(error);
    console.log("Google sign in was unsuccessful");
  };

  return (
    <section className="col-start-1 col-end-2 md:col-start-2 md:col-end-3 row-start-2 row-end-3 md:row-start-1 md:row-end-2 mx-3 sm:mx-0 md:my-auto">
      <div className=" w-full max-w-md bg-primaryOne px-6 py-8 rounded-md shadow-md mx-auto">
        <FormProvider {...formMethods}>
          <form className="" onSubmit={handleSubmit(onSubmit)}>
            <div className="w-full flex justify-around mb-2">
              <button
                className={`${
                  isLogin
                    ? "bg-secondaryTwo"
                    : "transition bg-transparent hover:bg-secondaryTwo"
                } text-white text-xs font-bold px-6 py-4 rounded-full`}
                type="button"
                onClick={() => setIsLogin(true)}
              >
                LOG IN
              </button>
              <button
                className={`${
                  !isLogin
                    ? "bg-secondaryTwo"
                    : "transition bg-transparent hover:bg-secondaryTwo"
                } text-white text-xs font-bold px-6 py-4 rounded-full`}
                type="button"
                onClick={() => changeScreen()}
              >
                SIGN UP
              </button>
            </div>
            <div>
              {!isLogin && (
                <div>
                  <Label labelName="Name" />
                  <Input inputName="name" type="text" bgColor="primaryTwo" />
                </div>
              )}
              <div>
                <Label labelName="Email" />
                <Input inputName="email" type="email" bgColor="primaryTwo" />
              </div>
              <div>
                <Label labelName="Password" />
                <Input
                  inputName="password"
                  type="password"
                  bgColor="primaryTwo"
                />
              </div>
            </div>
            <div className="text-center">
              <button
                type="button"
                onClick={() => setIsLogin(!isLogin)}
                className="text-neutral font-extralight text-xs pt-6"
              >
                {authData && <h1 style={{ color: "red" }}>{authData}</h1>}
                {!isLogin
                  ? "Already have an account? Log In"
                  : "Don't have an account? Sign Up"}
              </button>
            </div>

            <button className="bg-secondaryTwo hover:bg-secondaryOne transition px-4 py-3 w-full rounded-md text-white font-bold mt-4 shadow-md">
              {isLogin ? "Log In" : "Sign Up"}
            </button>
            <div className="flex items-center py-6">
              <div className="w-1/2 h-px bg-white bg-opacity-40"></div>
              <p className="text-white px-1 text-xs">OR</p>
              <div className="w-1/2 h-px bg-white bg-opacity-40"></div>
            </div>
            <div>
              <GoogleLogin
                clientId={process.env.REACT_APP_GOOGLE_CLIENT_ID}
                onSuccess={googleSuccess}
                onFailure={googleFailure}
                cookiePolicy="single_host_origin"
                render={(renderProps) => (
                  <button
                    className="bg-blue-600 hover:bg-blue-500 transition px-4 py-3 w-full rounded-md text-white font-bold mb-4 shadow-md"
                    type="button"
                    onClick={renderProps.onClick}
                    disabled={renderProps.disabled}
                  >
                    <i className="fab fa-google mr-2"></i>Continue with Google
                  </button>
                )}
              />
            </div>
          </form>
        </FormProvider>
      </div>
    </section>
  );
};

export default Auth;

还有最后一件事。在使用其属性之前检查嵌套对象,例如 error.response.data.message(您的 auth.js 操作文件)

import * as api from "../api";

export const signin = (formData, history) => async (dispatch) => {
  try {
    // login the user
    const { data } = await api.signIn(formData);
    dispatch({ type: "AUTH", data });
    history.push("/");
  } catch (error) {
    console.log("An error occured while ");
    const errMsg =
      error.response && error.response.data.message
        ? error.response.data.message
        : error.message;
    dispatch({ type: "ERROR", data: errMsg });
    console.log(errMsg);
  }
};

export const signup = (formData, history) => async (dispatch) => {
  try {
    // sign up the user
    const { data } = await api.signUp(formData);
    dispatch({ type: "AUTH", data });
    history.push("/");
  } catch (error) {
    console.log(error);
  }
};

希望对您有所帮助!