DEV Community

Cover image for How to Use TanStack-Query to Write Cleaner React Code as a Junior Developer
Elisabeth Leonhardt
Elisabeth Leonhardt

Posted on

How to Use TanStack-Query to Write Cleaner React Code as a Junior Developer

Showing data obtained by external sources is a core part of most frontend applications.

Most of the data comes from an API or a CMS. If the amount of data to be fetched is small, this can easily done with react-native hooks in combination with the fetch api. However, if the data flow between client and server grows more complicated, we are at risk of creating tons of unmaintainable spaghetti code.

To avoid this, we need a better tool for the job: React Query.

Here are the steps to get started with react query to improve your code:

1. Understand the difference between client state and server state

Client state lives in the browser, like form state, dark mode or whether a modal is opened or closed. Server state lives probably in some database and is served asynchronously.

Always use React Query for server state. Use native hooks like useState or useReducer for client state.

2. Install React-Query in your project

Follow the installation instructions and don't forget to set up the query client provider

3. In your code, replace data fetching code and states with the useQuery hook

Instead of writing this:

  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch('https://rickandmortyapi.com/api/character');
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        const result = await response.json();
        setData(result.results);
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    }

    fetchData();
  }, []);

Enter fullscreen mode Exit fullscreen mode

write this:

function fetchRickAndMortyCharacters() {
  return fetch('https://rickandmortyapi.com/api/character')
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      return response.json();
    })
    .then(data => data.results);
}

  const { data, isLoading, isError, error } = useQuery(['rickAndMortyCharacters'], fetchRickAndMortyCharacters);

Enter fullscreen mode Exit fullscreen mode

The data you need to render will be in the destructured data. Here is an example of how you can render the result:

  if (isLoading) return <p>Loading...</p>;
  if (isError) return <p>Error: {error.message}</p>;
  if (!data) return <p>No data available</p>;

  return (
    <ul>
      {data.map(character => (
        <li key={character.id}>{character.name}</li>
      ))}
    </ul>
  );
Enter fullscreen mode Exit fullscreen mode

4. Convert the useQuery hook into a custom hook

For better reusability, abstract this into a custom hook:

export function useRickAndMortyCharacters() {
  return useQuery(['rickAndMortyCharacters'], fetchRickAndMortyCharacters);
}

Enter fullscreen mode Exit fullscreen mode

now, from any component, you can just call the custom hook like so:

const { data, isLoading, isError, error } = useRickAndMortyCharacters();

Enter fullscreen mode Exit fullscreen mode

That's it! If you want to go any further, read the docs and play around with different query options or with mutations.

Thanks for reading!

Top comments (2)

Collapse
 
alvarovfon profile image
Álvaro Villamarín

I'm just learning the basics of tanstack and found this article useful. Thanks so much!

Collapse
 
leejinz profile image
Lee Jinz

This article is very helpful, thanks for sharing