22

I need to understand how can I setup a custom hook in React, for a POST method.

If I need to POST some data after a click, but I can't use the custom hook in an event handler, how can I do It?

I made a custom Hook with all the fetch logic and the relative reducers, but I don't know, how to use It in a click, without breaking the rules.

peterh
  • 11,875
  • 18
  • 85
  • 108
Fabio Russo
  • 271
  • 1
  • 3
  • 13

1 Answers1

30

All you need is a handler that triggers post method

const useFetchData = ({url, headers, payload}) => {
    const [res, setRes] = useState({data: null, error: null, isLoading: false});
    const [error, setError]
    // You POST method here
    const callAPI = useCallback(() => {
         setRes(prevState => ({...prevState, isLoading: true}));
         axios.post(url, headers, payload).then(res => {
            setRes({data: res.data, isLoading: false, error: null});
         }).catch((error) => {
            setRes({data: null, isLoading: false, error});
         })
    }, [url, headers, payload])
    return [res, callAPI];
}

Now you can use this hook in your code and on any event handler just call callAPI returned from the hook like

const MyFunc = () => {
   const [res, apiMethod] = useFetchData({url: 'some url here', headers: {ContentType: 'text/plain'}, payload: {}});

   return (
      <button onClick={() => {apiMethod()}} type="button">Submit data</button>
   )
}

You could event have payload defined in the component state and pass it on to the useFetchData as argument.

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • 3
    this solution won't work if you try to use apiMethod inside an useEffect. an infinite loop will happen – Gerardo May 24 '19 at 22:33
  • but in my case res i am getting {data:null,error:null,isLoading:false} even network shows correct value for response – Kiwi Rupela Jul 28 '20 at 14:40
  • for those using typescript the return type needs to be return [res, callAPI] as const; – Игор Ташевски Aug 18 '20 at 15:17
  • Yep - I got an infinite loop with `useEffect` and the API i was using rate limited me – Clifford Fajardo Oct 12 '20 at 17:27
  • 1
    @cacoder because your dependency array of `useCallback` for payload or headers may be an Object or Array and in javascript compare two similar object always return false for example `{} !== {} ` because they're compared with it's reference, for solving your problem you must change you dependency array to `[url, JSON.stringify(headers), JSON.stringify(payload)] ` –  Oct 17 '20 at 05:06