Home > Enterprise >  react axios custom hook trigger onClick and on useEffect()
react axios custom hook trigger onClick and on useEffect()

Time:05-20

I have a custom hook for the axios calls. I want to use it with useEffect() and also onSumbit() on forms. Right now, the values that are passed to the body of the customHook, are always empty. How can I fix this?

axios custom hook:

 const useHttp = ({ url, method, body = null, headers = null, autoRun = true }) => {
  const [response, setResponse] = useState(null);
  const [error, setError] = useState("");
  const [loading, setloading] = useState(true);

  const fetchData = async () => {
    api[method](url, headers, body)
      .then((res) => {
        setResponse(res.data);
      })
      .catch((err) => {
        setError(err);
      })
      .finally(() => {
        setloading(false);
      });
  };

  useEffect(() => {
    if (!autoRun) {
      return;
    }
    fetchData();
  }, [method, url, body, headers]);

  return { response, error, loading, setloading, fetchData };
};

export default useHttp;

usage:

    const useAuth = () => {
     const [registerFormValues, setRegisterFormValues] = useState({
        name: "",
        email: "",
        password: "",
        doctorId: "",
        personalNumber: "",
      });
    
    const { fetchData } = useHttp({
        autoRun: false,
        method: "post",
        url: "/authentication/register-pacient",
        headers: {
          "content-type": "application/json",
        },
        body: JSON.stringify({
          name: registerFormValues.name,
          email: registerFormValues.email,
          password: registerFormValues.password,
          doctorId: registerFormValues.doctorId,
          personalNumber: registerFormValues.personalNumber,
        }),
      });
   
    
      const submitHandlerRegister = async (values) => {
        setRegisterFormValues({
          name: values.firstName   " "   values.lastName,
          email: values.email,
          password: values.password,
          doctorId: values.doctorId,
          personalNumber: values.personalNumber,
        });
        console.log("registerFormValues", registerFormValues);
        fetchData();
      };
    
    return {   
        submitHandlerRegister,
      };
    };
    
    export default useAuth;

The submit handler is used in a formik form. The values (submit handler parameter, get the right values from the form)

CodePudding user response:

It's almost never a good idea to store same values in two diffrent places. You already have form values in FormikState, why do you need duplicate this data in useAuth's state?

When you call setRegisterFormValues and trying instantly access registerFormValues, there are still previous values. It will be updated during next render.

It is more useful to pass up-to-date values directly in fetchData function:

const fetchData = async (body) => {
    api[method](url, headers, body)
      .then((res) => {
        setResponse(res.data);
      })
      .catch((err) => {
        setError(err);
      })
      .finally(() => {
        setloading(false);
      });
  };

and usage:

const submitHandlerRegister = async (values) => {
    fetchData(values);
};

CodePudding user response:

The working code:

const useHttp = ({ url, method, body = null, headers = null, autoRun = true }) => {
  const [response, setResponse] = useState(null);
  const [error, setError] = useState("");
  const [loading, setloading] = useState(true);

  const fetchData = async (body) => {
    api[method](url, body)
      .then((res) => {
        setResponse(res.data);
      })
      .catch((err) => {
        setError(err);
      })
      .finally(() => {
        setloading(false);
      });
  };

  useEffect(() => {
    if (!autoRun) {
      return;
    }
    fetchData();
  }, [method, url, body, headers]);

  return { response, error, loading, setloading, fetchData };
};

export default useHttp;


usage:
    
const useAuth = () => {

  const { fetchData } = useHttp({
    autoRun: false,
    method: "post",
    url: "/authentication/register-pacient",
    headers: {
      "content-type": "application/json",
    },
  });


  const submitHandlerRegister = async (values) => {   
    fetchData(values);
  };

  return {
    submitHandlerRegister,
  };
};

export default useAuth;
  • Related