Home > Software engineering >  React useEffect OnSubmit Rendering Post api multiple times
React useEffect OnSubmit Rendering Post api multiple times

Time:01-18

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: "[email protected]",
    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;

Here onSubmit my backend api is rendering multiple times. i understand that when my state changes it will render everything in the component again, so i'm using useEfect but still the issue is occurring, is there something that i'm missing ?

do i need to use normal function instead of arrow function ? i'm new to react so got less idea on.

Any Idea how to tackle it ?

thank-you for checking it out.

enter image description here

CodePudding user response:

If you are referring to the OPTIONS call being the additional call here. Please read This Stackoverflow discussion

It is probably because of the way you are handling CORS in your backend.

CodePudding user response:

The useEffect manages an array that contains the state variables or functions which are kept an eye for any changes. These changes then trigger the callback function. The empty array indicates that the useEffect doesn’t have any dependencies on any state variables. Therefore, the callback function is only called once the page renders in this case.

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

CodePudding user response:

As you have passed array dependency [didSubmit] , as its value change it gonna re-render. But in your case you are not resetting the state value back to false. You have only set it to true once in you onSubmit method.

Suggestion I think, here you array dependency is meaningless because you are invoking onSubmit method on button click.

As your component mount and is there any need to call this method on component mount? you can remove this useEffect.

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

Your onSubmit Method:

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