# Part 72: Optimizing Data Fetching in React: Using React Query in Your NavBar

<figure><img src="https://159896965-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3LclXKUpANLoSt8DPdYV%2Fuploads%2FJK8G3Yjm1qHwjGSqwUcV%2F1675674296261.jpeg?alt=media&#x26;token=989182c4-9098-4bba-8dd9-52aeb4b0f941" alt=""><figcaption><p>[Pages] React Query</p></figcaption></figure>

With React Query set up in our application, it's time to leverage its power in our components. Today, we’ll focus on the NavBar component, where we'll replace traditional state management with React Query's `useQuery` hook for fetching user data. This transition not only simplifies our code but also enhances performance through caching and efficient data management.

### Transitioning from `useState` and `useEffect` to `useQuery`

#### Understanding `useQuery`

React Query's `useQuery` hook is a powerful tool for fetching and caching data. It requires:

1. **Query Key**: An identifier for the query, used for caching. In our case, we'll use `"user"` since we're fetching user data.
2. **Query Function**: A function that fetches the data, returning the user data or `undefined` if not authenticated.
3. **Options**: An object to configure caching and other behaviors, such as `staleTime` and `cacheTime`.

#### Implementing `useQuery` in NavBar

Let's see how to integrate `useQuery` into our NavBar component:

```javascript
// components/NavBar.js

import Link from 'next/link';
import { useQuery } from 'react-query';
import { fetchJson } from '../lib/api';

function NavBar() {
  // Using useQuery to fetch and cache user data
  const query = useQuery('user', async () => {
    try {
      return await fetchJson('/api/user');
    } catch (err) {
      return undefined; // User is not authenticated
    }
  }, {
    cacheTime: Infinity, // Cache data indefinitely
    staleTime: 30_000, // Data is fresh for 30 seconds
  });

  const user = query.data;

  const handleSignOut = async () => {
    await fetchJson('/api/logout');
    // FIXME: handle sign-out logic
  };

  console.log('[NavBar] user:', user);

  return (
    <nav>
      <Link href="/">Home</Link>
      {user ? (
        <button onClick={handleSignOut}>Sign Out</button>
      ) : (
        <Link href="/sign-in">Sign In</Link>
      )}
    </nav>
  );
}

export default NavBar;
```

#### Key Changes

* **Data Fetching**: We replaced `useState` and `useEffect` with `useQuery`, eliminating the need for manual state updates and error handling.
* **Caching**: By setting `staleTime` to 30,000 milliseconds (30 seconds), we ensure the user data is not refetched unnecessarily within this period.
* **Memory Management**: `cacheTime` set to `Infinity` keeps the user data in memory indefinitely, perfect for data needed across multiple pages.

### Testing and Observations

#### Initial Load

Upon page load, the NavBar uses `useQuery` to fetch user data from `/api/user`. The data is initially `undefined` until the API response is received, which then updates the UI.

#### Navigating Between Pages

With `staleTime` configured, navigating to different pages within 30 seconds does not trigger additional user data requests. React Query serves the data from its cache, enhancing performance and reducing server load.

#### Window Focus Behavior

By default, React Query refetches data when the window regains focus, ensuring up-to-date information. This is particularly useful if user authentication status can change, such as token expiration.

#### Handling Sign-Out

Currently, the sign-out logic is marked with a `FIXME`. To fully implement this, ensure the app state reflects the user's signed-out status. This might involve clearing local storage or redirecting to a sign-in page.

### Conclusion

Integrating React Query into your components can significantly streamline data fetching and caching. By using `useQuery`, we simplify the NavBar component, reduce redundant API calls, and enhance the user experience with responsive data updates.

In future posts, we'll continue exploring React Query's capabilities, including more complex use cases and configurations. Stay tuned as we delve deeper into optimizing your React applications!
