Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
September 28, 2022 06:53 pm GMT

Getting Started with React Query

The Missing Data Fetching Library

React-Query is often described as The missing data fetching library for React, because of the reason that React is a UI library that has no opinions on how we fetch the data from the server. The most basic form used by front-end developers to fetch the data is using JavascriptsfetchAPI, handling the requests with useEffect hook and managing the components states like loading, error, and resulting data using useState hook. Initially, the world is all fairyland but as soon as the project starts picking up stacks of complexity and we might require features like caching, synchronizing, and updating the server state, thats when the reality hits hard and developers are left with the following options:

- Build your way to fetch and manage data: Since React applicationsdo notcome with an opinionated way of fetching or updating data from your components so developers end up building their ways of fetching data. This usually means cobbling together component-based states and effects using React hooks and keeping on building as things are. Though this is not a scalable approach and results in issues for which we are finding solutions in the first place.

- Using react management libraries: Another way is to use the state management libraries for React applications like Redux, Mobix, etc which store and provide asynchronous data throughout the app. While most traditional state management libraries are great for working with client states, they arenot so great at working with async or server states.This is becausethe server state is completely different from the client state and remote as well.

According to React-Query docs, the server state:

  • Is persisted remotely in a location you do not control or own
  • Requires asynchronous APIs for fetching and updating
  • Implies shared ownership and can be changed by other people without your knowledge
  • Can potentially become "out of date" in your applications if you're not careful

Managing the server state with these libraries becomes even more challenging when the developers have to deal with caching, deduping multiple requests for the same data, updating stale data in the background, and performance optimizations like pagination and lazy loading data, etc.

The developers have to tackle all or most of these challenges and believe me were only scratching the surface here!

This is the hole that React-Query tries to fill up. It is one of the best if not the best, libraries for managing server state that works with zero-config and can be customized as per application needs.

According to React-Query docs, some advantages are as follows:

  • Reduction in Lines Of Code of your application
  • More emphasis on building new features instead of worrying about wiring up new server state data sources.
  • End-user satisfaction as data fetching is optimized and your application feels faster and more responsive.
  • Potentially help you save on bandwidth and increase memory performance

Installation

In your react app, You can install React Query via NPM

$ npm i @tanstack/react-query# or$ yarn add @tanstack/react-query

React query library module exports a provider component QueryClientProvider inside which we can wrap our App component.

import React from "react";import { QueryClient, QueryClientProvider } from "@tanstack/react-query";import { ReactQueryDevtools } from '@tanstack/react-query-devtools'const App = () => {  return (    <QueryClientProvider client={queryClient}>       {/* The rest of your application */}      <ReactQueryDevtools initialIsOpen={false} position="bottom-right" />    </QueryClientProvider>  );};

Wrapping our app with the provider enables our app to leverage all the features that React-Query provides. We also need to instantiate the query client and pass it as a prop to the provider component. Now every child component wrapped inside the provider can fetch data using react query!
Also, React-Query provides out-of-the-box dedicated Devtools to facilitate debugging during the development. It helps in visualizing all of the inner workings of React Query and will likely save you hours of debugging if you find yourself in a pinch!

The devtools are a separate package that you need to install:

$ npm i @tanstack/react-query-devtools# or$ yarn add @tanstack/react-query-devtools

By default, React Query Devtools are only included in bundles when process.env.NODE_ENV === 'development', so you don't need to worry about excluding them during a production build.

Setting up async mock API

To emulate the data fetching process We are going to use the JSON-Server to create a /companies route that returns a list of companies.
Using a standard approach to fetch the data and display it on the web page we use Reacts useEffect and useState hooks as follows:

import React, { useEffect } from "react";async function fetchCompanies() {  return await fetch(`http://localhost:4000/companies`).then((response) =>    response.json()  );}const Companies = () => {  const [companies, setCompanies] = React.useState([]);  const [isLoading, setIsLoading] = React.useState(true);  const [isError, setIsError] = React.useState(false);  useEffect(() => {    fetchCompanies()      .then((response) => {        setCompanies(response);        setIsLoading(false);      })      .catch((_error) => setIsError(true));  }, []);  if (isLoading) {    return <div>loading</div>;  }  if (isError) {    return <div>error occurred</div>;  }  return (    <div>      {companies.map((company) => {        return <div key={company.id}>{company.name}</div>;      })}    </div>  );};export default Companies;

It is evident from above that even for such a simple scenario we have to maintain 3 state variables to handle the application state.

Now let's try this with React-Query now

import React from "react";import { useQuery } from "@tanstack/react-query";async function fetchCompanies() {  return await fetch(`http://localhost:4000/companies`).then((response) =>    response.json()  );}const Companies = () => {  const {    isLoading,    data: companies,    isError,    error,  } = useQuery(["companies"], fetchCompanies);  if (isLoading) {    return <div>loading</div>;  }  if (isError) {    return <div>{error.message}</div>;  }  return (    <div>      {companies.map((company) => {        return <h1 key={company.id}>{company.name}</h1>;      })}    </div>  );};export default Companies;

Woah! What just happened? Whats this useQuery and what is it returning? Why arent we maintaining loading and error states separately?

Let us understand one thing at a time.

useQuery is the hook made available by React-Query that is used to fetch the data from external API resource. By definition, it can have 3 arguments

useQuery(QUERY_KEY, FETCH_FUNCTION, { OPTIONS });
  • QUERY_KEY is just a key that can uniquely identify a query across your application. You might come up with why the identification of any query is required? It is required as the data from the API might get outdated or the query response gets invalid, React-Query will trigger a re-fetch automatically when any of the above happens so it needs to know which query to re-fetch.

As per React query docs:

React Query manages query caching for you based on query keys. Query keys have to be an Array at the top level, and can be as simple as an Array with a single string, or as complex as an array of many strings and nested objects. As long as the query key is serializable, and unique to the query's data, you can use it!

  • FETCH_FUNCTION your data fetching logic goes here

  • OPTIONS object here we can configure our query response like stale time, cache time, enabled, etc. More on this in the next lessons.

useQuery hook returns various methods and variables that represent the query request phases and response like:

data: (3) [{}, {}, {}]dataUpdatedAt: 1654966057499error: nullerrorUpdateCount: 0errorUpdatedAt: 0failureCount: 0isError: falseisFetched: trueisFetchedAfterMount: trueisFetching: falseisIdle: falseisLoading: falseisLoadingError: falseisPlaceholderData: falseisPreviousData: falseisRefetchError: falseisRefetching: falseisStale: trueisSuccess: truerefetch:  ()remove:  ()status: "success"

You can go through these but at the moment we only require the isLoading and isError states. You can see here how react query internally handles all the states automatically without any issues.
For the query response you can have a look at React-Query Devtools as well, just click on the query key and the details of that query will be opened as below

devtools screenshot

Thats how React-Query abstracts away a lot of data fetching and management logic from the component.
In the next chapter, we will dive into the configuration options that we can use to configure the query using the options parameter in the useQuery hook.

Till then happy coding!


Original Link: https://dev.to/nischal_dutt/getting-started-with-react-query-30g7

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To