# Part 73: Leveraging Custom Hooks in React: Simplifying Data Fetching with useUser

<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>

React's ecosystem offers a plethora of tools to streamline and enhance component development. Among these, hooks stand out as a pivotal feature, enabling developers to handle side effects and state management efficiently in functional components. In this blog post, we'll explore how to create a custom hook, `useUser`, to encapsulate data-fetching logic, making your codebase more organized and reusable.

### The Power of Custom Hooks

Custom hooks in React are functions prefixed with "use" that allow you to extract component logic into reusable functions. This approach not only tidies up your components but also promotes reusability and a clean separation of concerns.

### Moving Data Fetching Logic to a Custom Hook

Let's walk through the process of extracting the user data-fetching logic from a component and encapsulating it in a custom hook.

#### Step 1: Create a New Hooks Directory

First, organize your project structure by creating a `hooks` directory at the top level. This is where we'll store our custom hooks, making them easily accessible across the project.

#### Step 2: Implementing the `useUser` Hook

Within the `hooks` directory, create a new file named `user.js`. Here, we'll define our custom `useUser` hook:

```javascript
// File: hooks/user.js

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

export function useUser() {
  const query = useQuery('user', async () => {
    try {
      return await fetchJson('/api/user');
    } catch (err) {
      return undefined;
    }
  }, {
    cacheTime: Infinity,
    staleTime: 30_000, // ms
  });
  return query.data;
}
```

In this hook, we're using the `useQuery` hook from a data-fetching library to fetch and cache user data. The `fetchJson` function handles the API request, and the query's result is returned as `query.data`.

#### Step 3: Refactoring the NavBar Component

With the `useUser` hook in place, we can simplify components like `NavBar` by removing redundant code and focusing on rendering logic:

```javascript
// File: components/NavBar.js

import Link from 'next/link';
import { useUser } from '../hooks/user';
import { fetchJson } from '../lib/api';

function NavBar() {
  const user = useUser();

  const handleSignOut = async () => {
    await fetchJson('/api/logout');
  };

  return (
    <nav>
      {user ? (
        <span>Signed in as {user.name}</span>
      ) : (
        <span>Not signed in</span>
      )}
      <button onClick={handleSignOut}>Sign out</button>
    </nav>
  );
}

export default NavBar;
```

#### Step 4: Testing and Verifying

After refactoring, it's crucial to test your application to ensure everything works as expected. If the NavBar displays "Signed in as Alice," the refactoring was successful.

#### Step 5: Reusing Logic Across Components

One of the major benefits of custom hooks is their reusability. Suppose you want to display a special offer message on a `ProductPage` component:

```javascript
// File: components/ProductPage.js

import { useUser } from '../hooks/user';

function ProductPage() {
  const user = useUser();

  return (
    <div>
      <h1>Product Name</h1>
      <p>Price: $100</p>
      {user && <p>Only for {user.name}!</p>}
    </div>
  );
}

export default ProductPage;
```

With the `useUser` hook, you can effortlessly access user data in any component without duplicating code.

### Conclusion

By encapsulating data-fetching logic in custom hooks like `useUser`, you enhance code reusability and maintainability. This approach keeps components focused on rendering, simplifies state management, and eliminates the need for more complex state management solutions. Embrace custom hooks for a cleaner and more efficient React development experience!
