Home > Back-end >  What's the best practice to wait for fetch call in React?
What's the best practice to wait for fetch call in React?

Time:10-21

In my App.js script it looks like this:

import React from "react";

function App() {

  const [colorsData, setColorsData] = React.useState();

  React.useEffect(() => {
    const url = `https://www.thecolorapi.com/scheme?hex=0047AB&rgb=0,71,171&hsl=215,100%,34%&cmyk=100,58,0,33&mode=analogic&count=6`
    fetch(url)
      .then(res => res.json())
      .then(data => setColorsData(data))
  }, [])

  console.log(colorsData);

  return (
    <div className="App">
      <h1>{colorsData ? colorsData.colors[0].hex.value : "Loading..."}</h1>
      <img src={colorsData ? colorsData.colors[0].image.named : "Loading..."} />
    </div>
  );
}
export default App;

Instead of checking if there's colorsData or not in every element which approach should I use for more clean code? If I don't check if there's colorsData, I get an error for undefined.

CodePudding user response:

You can use a custom hook like:

import { useEffect, useState } from "react";

function useData(url) {
  const [loading, setLoading] = useState(true);
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        setData(data);
        setLoading(false);
      });
  }, [url]);

  return { data, loading };
}

function App() {
  const { data, loading } = useData(
    "https://www.thecolorapi.com/scheme?hex=0047AB&rgb=0,71,171&hsl=215,100%,34%&cmyk=100,58,0,33&mode=analogic&count=6"
  );

  return (
    <div className="App">
      {loading ? (
        "Loading..."
      ) : (
        <>
          <h1>{data.colors[0].hex.value}</h1>
          <img src={data.colors[0].image.named} />
        </>
      )}
    </div>
  );
}
export default App;

CodePudding user response:

The good people at Vercel created a great react hook library called SWR (stale while revalidate)

SWR documentation

The name “SWR” is derived from stale-while-revalidate, a HTTP cache invalidation strategy popularized by HTTP RFC 5861. SWR is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.

Reasons to use instead of creating your own hook (from their website):

  • Fast, lightweight and reusable data fetching
  • Built-in cache and request deduplication
  • Real-time experience
  • Transport and protocol agnostic
  • SSR / ISR / SSG support
  • TypeScript ready
  • React Native

Even more reasons (not bulleted to save space):

Fast page navigation, Polling on interval, Data dependency, Revalidation on focus, Revalidation on network recovery, Local mutation (Optimistic UI), Smart error retry, Pagination and scroll position recovery, and React Suspense

Implementation example:

import useSWR from 'swr'

// you can use any fetcher with SWR, this is just a wrapper for the native fetch function
const fetcher = (url) => fetch(url).then((res) => res.json());

function App() {
  const url = `https://www.thecolorapi.com/scheme?hex=0047AB&rgb=0,71,171&hsl=215,100%,34%&cmyk=100,58,0,33&mode=analogic&count=6`

  // error is optional, if you want to show your user that an error occured
  const { data, error } = useSWR(url, fetcher)

  return (
    <div className="App">
      <h1>{colorsData ? data.colors[0].hex.value : "Loading..."}</h1>
      <img src={colorsData ? data.colors[0].image.named : "Loading..."} />
    </div>
  );
}
export default App;
  • Related