javascriptreactjsaxios

React Hook for a POST call onClick


I have a button, onClick of that button I want to make a POST call with some data user has filled in an input field, stored in state, and then redirect the user to another page.

My current code looks like this, but I get an error:

React Hook "usePost" is called in function "onAccept" which is neither a React function component or a custom React Hook function

And the code doesn't work. I have created my own hook for POST calls.

What might a way to make the desired functionality work?

What I'm after is the ability to make a POST call and redirect.

Simplified example:

// my function
const onAccept = () => {
  const { data, loading, error } = usePost(
    "MY_URL",
    { DATA: MY_DATA }
  );
  if (data && !error) {
    navigate(`/`);
  }
};

// return
<button onClick={() => onAccept()}

Solution

  • Yes, You are calling usePost hook inside of onAccept function. You should follow react hook rule.

    To solve your problem, you can do like that:

    your custom hook file:

    export const usePost = () => {
      const [status, setStatus] = useState()
    
      const handlePost = useCallback(async (url, data) => {
        // your api request logic in here, bellow only show example
        try {
          const {data, status} = await apiCall(url, data)
          if (data && status === 200) navigate(`/`)
        } catch (error) {
          console.log(error)
        }
      }, [])
    
      return { handlePost }
      // to return status to component, you can use bellow.
      // return { status, handlePost }
    }
    

    then your component:

    const YourComponent: React.FC = () => {
      const { handlePost } = usePost()
      // To get status: const { status, handlePost } = usePost()
      // your other hooks in here
      // Check status
      useEffect(() => {
        if (status === 200) {
          // whatever you want to do
        }
      }, [status])
      
      return (
        <>
          // Your component UI here
          ...
          <button onClick={() => handlePost(url, data)}>
        </>
      )
    }
    

    You should call your custom hooks(for example: usePost) at the top level of component, not nested function body as like as you were doing in your code (onAccept function body).