DEV Community

Cover image for Building custom hooks in React to fetch Data

Building custom hooks in React to fetch Data

Shahid Rizwan on September 04, 2021

Fetching data from the backend is one of the crucial parts of the web application. For every application to work dynamically, it fetches the data f...
Collapse
 
lowlifearcade profile image
Sonny Brown • Edited

Good stuff. I like to use a custom hook I made called useStateAndLocalStorage. I love the self documenting nature of custom hooks.

Collapse
 
morganjay profile image
James Morgan

Please I'd like to see how that works. 🤔

Maybe I'll like it too

Collapse
 
imrishabh18 profile image
Rishabh Gupta

Check out my blog on this James.

dev.to/imrishabh18/simplest-custom...

Thread Thread
 
morganjay profile image
James Morgan

Thanks!

Thread Thread
 
lowlifearcade profile image
Sonny Brown

That's pretty close to what I made.

Collapse
 
ehaynes99 profile image
Eric Haynes • Edited

That's not any simpler... It's just using the old Promise api...

 
ehaynes99 profile image
Eric Haynes • Edited

Note that the former reply was someone else, so no one "kept using 'old'". It is, in fact, older, but we can refer to it as "the .then syntax".

To each their own, but the allure of async/await is that the code reads exactly the same as it would if it were synchronous. There is a valid argument for consistency. E.g. it's pretty much universally accepted that we don't intermittently use callbacks for async, even if it would save a line or 2.

It's not "way more complex", either. It's slightly more verbose, and only in a rare set of cases. The .then syntax is only cleaner where you can constrain the action to lambda expressions and have at least 4 of them. As soon as you need a block for any of them, IMO it's rather messy. What is simply another line with async/await becomes a new function, another level of nesting, and a new scope. It takes a hit for readability when shorter than 4 as well, since formatters like prettier will inline:

myApi.getOrder(123).then(setOrder).catch(setError);
Enter fullscreen mode Exit fullscreen mode

So yes, in the cases where you have the catch in the same place as the call, can chain 4 or more operations that are all one liners, and never need to refer to something in a prior step of the chain, it's slightly cleaner, but it's rare enough that I wouldn't fault anyone for just forgetting about the syntax altogether.

const fetch1 = (orderNum) => {
  fetch(`/api/orders/${orderNum}`)
    .then((response) => response.json())
    .then(({ products }) => {
      setProducts(products);
      setError(null);
    })
    .catch((error) => {
      logger.error(error);
      setError(error);
    })
    .finally(() => setLoading(false));
};

// vs
const fetch2 = async (orderNum) => {
  try {
    const response = await fetch(`/api/orders/${orderNum}`);
    const { products } = await response.json();

    setProducts(products);
    setError(null);
  } catch (error) {
    logger.error(error);
    setError(error);
  }
  setLoading(false);
};
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
shifi profile image
Shifa Ur Rehman

And Finally!

Collapse
 
markyangit profile image
Gabriel Markyan

A good thing to note about this is that using custom hooks and hooks inside a useEffect causes an infinite loop.

 
hernanfarruggia profile image
Hernán Farruggia

I don't see any complexity in any of those... 🤷🏻‍♂️ They just have different sintax, and usually which one to use, will depend on the conventions of your project... Some companies decide to go with async to use latest festures, others prefer to stay with plain old promises... These sre just different points of view...

 
marceliwac profile image
Marceli-Wac • Edited

There is also the useCallback hook which can be used to create a memoized function that, when passed to useEffect dependency array, doesn't triger re-renders.

Collapse
 
mnlfischer profile image
Manuel

You should also check:
kent.dev/blog/stop-using-isloading...

Collapse
 
shaedrizwan profile image
Shahid Rizwan

Sure Manuel. Thank you for the article.

Collapse
 
khasky profile image
Khasky
Collapse
 
slimani_21 profile image
Slimani Mohammed

Thanks for the article. I think it would be better to set the error to null before fetching so that one error in fetching won't stay for all future fetch calls.

Collapse
 
rahulxyz profile image
Rahul Gupta

How would you handle different http methods? Here you have 1 hook using only get().

Collapse
 
shaedrizwan profile image
Shahid Rizwan

This hook is specifically for fetching data (GET). You can customize it by passing the HTTP method and body as parameter to the hook and use it inside.

 
marceliwac profile image
Marceli-Wac

I'm not sure I understand what you mean, can you elaborate?

Collapse
 
markyangit profile image
Gabriel Markyan

Yes, of course. But some linters require all the functions, custom hooks and external data at the dependency array. I'm saying because I've been through this.

Collapse
 
juancor181192 profile image
Juan Carlos Otero Roca

I use axios

Collapse
 
mustafazahedi profile image
Mustafa Zahedi

How fetch again after submitting any form if need in some case?