【问题标题】:React useEffect OnSubmit Rendering Post api multiple timesReact useEffect OnSubmit Rendering Post api 多次
【发布时间】:2023-01-18 20:14:41
【问题描述】:
import React, { useState, useEffect } from "react";
import Axios from "axios";
import { Link, Navigate } from "react-router-dom";

import "../assets/css/login.css";

import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

import API from "../backend";

import { isAutheticated, authenticate } from "../auth";

const Login = () => {
  const [values, setValues] = useState({
    email: "george@gmail.com",
    password: "12345678",
    error: "",
    regDirect: false,
    success: false,
  });

  const [didSubmit, setDidSubmit] = useState(false);

  const { email, password, regDirect } = values;

  const newPost = {
    email: email,
    password: password,
  };

  const user = isAutheticated();

  const onHandleChange = (val) => (event) => {
    setValues({ ...values, error: "", [val]: event.target.value });
  };

  const performRedirect = () => {
    if (regDirect) {
      if (user.user_Role === "admin") {
        return <Navigate to="/contact" />;
      } else {
        return <Navigate to="/" />;
      }
    }
    if (isAutheticated()) {
      return <Navigate to="/" />;
    }
  };

  const axiosPostCall = async () => {
    try {
      const res = await Axios.post(`${API}/login`, newPost);
      // enter you logic when the fetch is successful
      console.log(`data here: `, res);

      authenticate(res.data, () => {
        setValues({
          ...values,
          email: "",
          password: "",
          error: "",
          regDirect: true,
          success: true,
        });
      });
    } catch (error) {
      console.log(`error log: `, error);
      setValues({
        ...values,
        error: error.response.data.error,
        success: false,
      });
    }
  };

  useEffect(() => {
    if (didSubmit) {
      axiosPostCall();
    }
  }, [didSubmit]);

  const onSubmit = (event) => {
    event.preventDefault();
    setValues({ ...values, error: "" });
    setDidSubmit(true);
  };

  return (
    <>
      <ToastContainer
        position="top-right"
        autoClose={false}
        newestOnTop={false}
        closeOnClick
        rtl={false}
        pauseOnFocusLoss
        draggable
        theme="colored"
      />
      <div className="container">
        {values.error !== "" ? (
          toast(`${values.error}`, {
            position: "top-right",
            autoClose: false,
            hideProgressBar: true,
            closeOnClick: true,
            pauseOnHover: true,
            draggable: true,
            progress: undefined,
            theme: "dark",
          })
        ) : (
          <></>
        )}
        {values.success === true ? (
          toast(`Successfully LoggedIn`, { type: "success" })
        ) : (
          <></>
        )}

        {performRedirect()}
        <div className="row justify-content-center mt-5">
          <div className="col-lg-4 col-md-6 col-sm-6">
            <div className="card shadow">
              <div className="card-title text-center border-bottom">
                <h2 className="p-3">Login</h2>
              </div>
              <div className="card-body">
                <form>
                  <div className="mb-4">
                    <label className="form-label">Username/Email</label>
                    <input
                      type="text"
                      className="form-control"
                      onChange={onHandleChange("email")}
                      value={email}
                    />
                  </div>
                  <div className="mb-4">
                    <label className="form-label">Password</label>
                    <input
                      type="password"
                      className="form-control"
                      onChange={onHandleChange("password")}
                      value={password}
                    />
                  </div>
                  <div className="mb-4">
                    <input
                      type="checkbox"
                      className="form-check-input"
                      id="remember"
                    />
                    <label className="form-label">Remember Me</label>
                  </div>
                  <div className="d-grid">
                    <button
                      type="submit"
                      onClick={onSubmit}
                      className="btn text-light main-bg"
                    >
                      Login
                    </button>
                  </div>
                </form>
              </div>
            </div>
          </div>
        </div>
      </div>
      <br />
    </>
  );
};

export default Login;

这里 onSubmit 我的后端 api 呈现多次。我知道当我的状态改变时,它会再次渲染组件中的所有内容,所以我正在使用 useEfect 但问题仍然存在,我是否遗漏了什么?

我需要使用普通函数而不是箭头函数吗?我是新手,所以不太了解。

任何想法如何解决它?

谢谢你检查出来。

【问题讨论】:

    标签: node.js reactjs react-hooks


    【解决方案1】:

    如果您指的是 OPTIONS 调用是此处的附加调用。请阅读This Stackoverflow discussion

    这可能是因为您在后端处理 CORS 的方式。

    【讨论】:

      【解决方案2】:

      useEffect 管理一个包含状态变量或函数的数组,这些变量或函数会密切关注任何变化。然后这些更改会触发回调函数。 空数组表示 useEffect 不依赖于任何状态变量。因此,在这种情况下,回调函数只会在页面呈现后调用。

        useEffect(() => {
          if (didSubmit) {
            axiosPostCall();
          }
        }, []);
      

      【讨论】:

        【解决方案3】:

        当您传递了数组依赖项 [didSubmit] 时,随着它的值发生变化,它将重新渲染。但在您的情况下,您不会将状态值重置回 false。您只在 onSubmit 方法中将其设置为 true 一次。

        建议我认为,在这里你的数组依赖是没有意义的,因为你在点击按钮时调用 onSubmit 方法。

        当您的组件挂载时,是否需要在组件挂载时调用此方法?您可以删除此 useEffect。

          useEffect(() => { axiosPostCall(); }, [didSubmit]);
        

        您的 onSubmit 方法:

        const onSubmit = (event) => {
        event.preventDefault();
        setValues({ ...values, error: "" });
        axiosPostCall()};
        

        【讨论】:

          猜你喜欢
          • 2020-01-05
          • 1970-01-01
          • 1970-01-01
          • 2021-03-23
          • 2022-11-26
          • 2021-06-04
          • 2021-12-28
          • 2022-12-26
          • 2023-01-27
          相关资源
          最近更新 更多