One of the challenges we face when building an application with React is determining a code pattern for fetching data from the server. The most common way to handle data fetching in React is to use the global state as a mechanism to determine the current status of the fetch operation.

Here is an example of fetching data from Star Wars API:

import React, {useState, useEffect} from 'react';
import axios from 'axios';

// regular fetch with axios
function App() {
  const [isLoading, setLoading] = useState(false)
  const [isError, setError] = useState(false)
  const [data, setData] = useState({});

  useEffect(() => {
    const fetchData = async () => {
      setError(false);
      setLoading(true);

      try {
        const response = await axios('http://swapi.dev/api/people/1/');

        setData(response.data);
      } catch (error) {
        setError(true);
      }
      setLoading(false);
    };
    fetchData()
  }, []);
return (
    <div className="App">
      <h1>React Query example with Star Wars API</h1>
      {isError && <div>Something went wrong ...</div>}

      {isLoading ? (
        <div>Loading ...</div>
      ) : (
        <pre>{JSON.stringify(data, null, 2)}
        </pre>
      )}
    </div>
  );
}
export default App;

The code above requires both useState and useEffect hooks and uses three different states to store data and determine whether the application is fetching data or already has an error response from the API. This pattern is repeated over and over again for most of your application data fetching logic.

And that’s not all. The most common problems with data fetching in React includes:

  • Data is shared across all app instance and can be changed by other people
  • Data could be “stale” and needs to be refreshed
  • Handle caching and invalidating data to optimize the request operation

Finally, there is also the problem of having the local state which commonly stores your user’s preferences like theme and sidebar config coupled with the remote state which holds the data fetched from API:

//what global state commonly look like nowadays
const state = {
  theme: "light",
  sidebar: "off",
  followers: [],
  following: [],
  userProfile: {},
  messages:[],
  todos:[],
}

Wouldn’t it be nice if you could separate the local state from the remote state? And what if you can reduce the amount of boilerplate code you need to write for data fetching?

One solution would be to create your own custom hook to handle fetching and handling of data. That’s a completely valid solution. You can also share and manage this hook in a component hub like Bit (Github). This way you’ll have it available for any project you’re working on (it can be as a pure hook but also as part of other reusable “smart components”).

Image for post

Example: browsing through shared React components on Bit.dev

Another solution and one that we’ll be exploring here in-depth is React Query. This library will help you to fetch, synchronize, update, and cache your remote data while also reducing the amount of code you need to write by providing you two simple hooks and one utility function.

To get the most out of this article, please download this sample repo that I’ve modified from the author:

Image for post

React Query Sample App

This small React app will retrieve an array of strings from the API route using axios. You can put a new string into the array by using the provided form. It also has the React Query DevTools opened so you can see the cached data in real-time.

#react #web-development

How and Why You Should Use React Query
32.50 GEEK