简体   繁体   中英

Async function passed as prop into React component causing @typescript-eslint/no-misused-promises error

I have the following asynchronous submitNewPatient function which is throwing @typescript-eslint/no-misused-promises error message from elint. Is it possible to adjust the function such that it removes this error?

const submitNewPatient = async (values: PatientFormValues) => {
    try {
      const { data: newPatient } = await axios.post<Patient>(
        `${apiBaseUrl}/patients`,
        values
      );
      dispatch({ type: "ADD_PATIENT", payload: newPatient });
      closeModal();
    } catch (e: unknown) {
      if (axios.isAxiosError(e)) {
        console.error(e?.response?.data || "Unrecognized axios error");
        setError(
          String(e?.response?.data?.error) || "Unrecognized axios error"
        );
      } else {
        console.error("Unknown error", e);
        setError("Unknown error");
      }
    }
  };

Component used to pass function as a prop:

<AddPatientModal
        modalOpen={modalOpen}
        onSubmit={submitNewPatient}
        error={error}
        onClose={closeModal}
      />

I have also tried the following which removes the eslint error message based. However, seems like I am not entering the async code block (perhaps not triggering the async() function):

  const submitNewPatient = (values: PatientFormValues) => {
    async () => {
      try {
        const { data: newPatient } = await axios.post<Patient>(
          `${apiBaseUrl}/patients`,
          values
        );
        dispatch({ type: "ADD_PATIENT", payload: newPatient });
        closeModal();
      } catch (e: unknown) {
        if (axios.isAxiosError(e)) {
          console.error(e?.response?.data || "Unrecognized axios error");
          setError(
            String(e?.response?.data?.error) || "Unrecognized axios error"
          );
        } else {
          console.error("Unknown error", e);
          setError("Unknown error");
        }
      }
    };
  };

I think the problem is with the async code block syntax. You need it to make it an IIFE (Immediately-invoked Function Expression for it to be executed immediately.

(async () => {
    await someAsyncFunction();
})();

Your submitNewPatient becomes -

const submitNewPatient = (values: PatientFormValues) => {
    (async () => {
      try {
        const { data: newPatient } = await axios.post<Patient>(
          `${apiBaseUrl}/patients`,
          values
        );
        dispatch({ type: "ADD_PATIENT", payload: newPatient });
        closeModal();
      } catch (e: unknown) {
        if (axios.isAxiosError(e)) {
          console.error(e?.response?.data || "Unrecognized axios error");
          setError(
            String(e?.response?.data?.error) || "Unrecognized axios error"
          );
        } else {
          console.error("Unknown error", e);
          setError("Unknown error");
        }
      }
    })();
  };

The problem is not in your code but in the ESLint rule or the ESLint config. React 17 and later can handle async functions as event handlers.

The IIFE gets rid of the ESLint error but the error should not appear in the first place. Unless you are using React 16 or earlier.

There was a lengthy discussion about the rule on Github .

The proposed solution is to remove the check for attributes or arguments:

{
  "@typescript-eslint/no-misused-promises": [
    "error",
    {"checksVoidReturn": {"attributes": false}}
  ]
}

https://typescript-eslint.io/rules/no-misused-promises/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM