0

I have a Login component and I receive that error: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak. I googled for the error and found some people having the same issue and I tried to solve it like them, but it didn't work for me. Why I have this error, and how do I fix it? Thanks

COMPONENT LOGIN

import React, { useState, useContext, useEffect } from "react";
import { useLocation } from "wouter";
import logic from "../../logic";
import { AuthContext } from "../../context/AuthContext";
import validate from "./validateRulesLogin";
import literals from "../../common/i18n/literals";
import "./index.css";

export default function Login(language) {
  const [, setAuth] = useContext(AuthContext);
  const [, pushLocation] = useLocation();
  const [messageError, setMessageError] = useState("");
  const [errorsValidateForm, setErrorsValidateForm] = useState({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [data, setData] = useState({ email: "", password: "" });

  const { lang } = language;

  const { login_notRegister } = literals;

  useEffect(() => {}, [errorsValidateForm, isSubmitting]);

  let isCancelled = false;
  async function handleOnSubmit(e) {
    e.preventDefault();
    if (!isSubmitting) {
      let errorsForm = validate(data, lang);
      if (Object.keys(errorsForm).length === 0 && !isCancelled) {
        setIsSubmitting(true);
        const { email, password } = data;
        try {
          await logic.loginUser(email, password, lang);
          setAuth(true);
          setIsSubmitting(false);
          pushLocation("/");
        } catch (error) {
          setMessageError(error.message);
          setIsSubmitting(false);
          setTimeout(() => {
            setMessageError("");
          }, 3000);
        }
      }
      setErrorsValidateForm(errorsForm);
    }
    return () => {
      isCancelled = true;
    };
  }

  const handleOnChangeData = (e) => {
    e.preventDefault();
    setData({
      ...data,
      [e.target.name]: e.target.value,
    });
  };

  return (
    <>
      {messageError && (
        <div className="message">
          <p className="messageError">{messageError}</p>
        </div>
      )}
      <section className="hero is-fullwidth">
        <div className="hero-body">
          <div className="container">
            <div className="columns is-centered">
              <div className="column is-4">
                <form id="form" onSubmit={(e) => handleOnSubmit(e)} noValidate>
                  <div className="field">
                    <p className="control has-icons-left">
                      <input
                        className="input"
                        name="email"
                        type="email"
                        placeholder="Email"
                        onChange={handleOnChangeData}
                        required
                      />
                      <span className="icon is-small is-left">
                        <i className="fas fa-envelope"></i>
                      </span>
                    </p>
                    {errorsValidateForm.email && (
                      <p className="help is-danger">
                        {errorsValidateForm.email}
                      </p>
                    )}
                  </div>
                  <div className="field">
                    <p className="control has-icons-left">
                      <input
                        className="input"
                        name="password"
                        type="password"
                        placeholder="Password"
                        onChange={handleOnChangeData}
                        required
                      />
                      <span className="icon is-small is-left">
                        <i className="fas fa-lock"></i>
                      </span>
                    </p>
                    {errorsValidateForm.password && (
                      <p className="help is-danger">
                        {errorsValidateForm.password}
                      </p>
                    )}
                  </div>
                  <div className="field">
                    <p className="control">
                      <button type="submit" className="button is-success">
                        Login
                      </button>
                    </p>
                  </div>
                  <div>
                    <a href="/register">{login_notRegister[lang]}</a>
                  </div>
                </form>
              </div>
            </div>
          </div>
        </div>
      </section>
    </>
  );
}

skyboyer
  • 22,209
  • 7
  • 57
  • 64
ccnat
  • 125
  • 2
  • 13
  • Hey @ccnat, try some of the solutions in this SO post: https://stackoverflow.com/questions/53949393/cant-perform-a-react-state-update-on-an-unmounted-component – kykyi Jun 28 '21 at 09:26
  • 1
    The link that bashford7 gave is great, but it assumes you already understand the issue. If you're not familiar, this error pops up bc at some point, your component mounts. While mounted, it calls some function, usually an async fn, in your case `handleOnSubmit`. Within that fn, some state is set. But between `handleOnSubmit` and some state being set, the component unmounts. So trying to call any state setters on an unmounted component will error error. It is up to you to understand your logic flow and why your component may be unmounting between `handleOnSubmit` and any state setters – Seth Lutske Jun 28 '21 at 16:06

0 Answers0