0

I am validating fields with react-hook-form and besides having fields as required, I also run the toast to show user that field is required.

I use the following function to achieve it:

const runError = () => {
    if (!isValid && Object.keys(errors).length > 0) {
      toast.error("Please fill required fields", {
        icon: <ErrorIcon />,
        closeButton: <CloseIcon />,
      });
      return <div></div>;
    } else {
      return null;
    }
  };

and then call {runError()} in JSX.

it works but issue is that when I fill required field, toast still runs once after that. Why?

I have onPost={handleSubmit((data) => handleFormSubmit("post", data))} and also

const handleFormSubmit = async (
    action: "save" | "post",
    data: TestModel
  ) => {
    if (action === "save") {
      const newModel: TestDto = { ...model, ...data };
      await saveHandler(newModel);
    } else if (action === "post") {
      const newModel: TestDto = { ...model, ...data };
      await saveHandler(newModel);
      await postHandler();
    }
  };
NikaA3
  • 19
  • 3

2 Answers2

1

when handleFormSubmit updates the state, it triggers a re-render, causing runError() to be called again, even if the required field has already been filled in. This results in the error message being displayed twice.

To fix this issue, you can try using the useEffect hook to call runError() only when the form has been submitted and the errors have changed

  useEffect(() => {
    runError();
  }, [errors]);
oluroyleseyler
  • 802
  • 2
  • 5
  • onPost={handleSubmit((data) => { clearErrors(); handleFormSubmit("post", data); })} I added clearErrors() like this but it still gave me an extra toast. Maybe i did something wrong – NikaA3 May 03 '23 at 13:59
  • no i meant not like that, pls can you edit your question again includes your form and function codes to make me get you better – oluroyleseyler May 03 '23 at 14:01
  • I just updated it – NikaA3 May 03 '23 at 14:09
  • okay can you use useEffect like my edited answer ? – oluroyleseyler May 03 '23 at 14:18
  • Shall I use useEffect after my runError function? const runError = () => { if (!isValid && Object.keys(errors).length > 0) { toast.error("Please fill required fields", { icon: , closeButton: , }); return
    ; } else { return null; } }; useEffect(() => { runError(); }, [errors]); Also just call runError() inside useEffect? Because I call runError in JSX
    – NikaA3 May 03 '23 at 14:30
  • yes you can do that, also you can take runError function inside useEffect.. it is your own choose – oluroyleseyler May 03 '23 at 18:09
0

May be you have to turn off strict-mode as react rerenders your component twice in strict-mode to help catch any errors