React LogoSWR

SWR stands for Stale-While-Revalidate, a caching strategy popularized by HTTP RFC 5861. In the context of front-end development, SWR is a lightweight React Hooks library for data fetching. It provides a flexible and powerful way to fetch, cache, and revalidate data in your React applications, making data management simpler and more efficient.

Why Use SWR?
Modern web applications frequently need to fetch data from APIs. Managing loading states, error states, caching, revalidation, and synchronization across multiple components can become complex. SWR addresses these challenges by:
* Automatic Revalidation: Automatically revalidates data when the component mounts, when the window regains focus, or on an interval, ensuring your UI displays fresh data without explicit manual triggers.
* Caching: Caches fetched data in memory, so subsequent requests for the same data key are served instantly from the cache while a background revalidation happens. This provides a perceived performance boost.
* Real-time Experience: The "stale-while-revalidate" strategy means users instantly see cached (stale) data, and then the UI transparently updates with the fresh data once it's fetched, providing a smooth, non-blocking user experience.
* Error Handling and Retries: Built-in error handling and exponential backoff retry mechanisms.
* Loading States: Provides `isLoading` and `isValidating` states to easily manage UI feedback during data fetching and revalidation.
* TypeScript Support: Excellent type safety.
* Lightweight and Performant: Minimal bundle size and optimized for performance.

How it Works:
At its core, SWR's `useSWR` hook takes two main arguments:
1. `key`: A unique identifier (usually a string, like an API endpoint URL) for the data you want to fetch. SWR uses this key to cache the data.
2. `fetcher`: An asynchronous function that actually fetches your data (e.g., using `fetch`, `axios`). This function receives the `key` as its argument.

When `useSWR(key, fetcher)` is called:
1. It first checks if there's cached data for the given `key`. If so, it immediately returns the cached data (stale data).
2. In the background, it executes the `fetcher` function to retrieve the latest data.
3. Once the new data arrives, it updates the cache and re-renders the component with the fresh data.
4. If an error occurs during fetching, it returns the error.

This "stale-while-revalidate" pattern ensures that users always see *something* quickly, even if it's slightly outdated, while the latest data is being fetched in the background.

Installation:
```bash
npm install swr
# or
yarn add swr
```

Example Code

import React from 'react';
import useSWR from 'swr';

// A simple fetcher function that uses the native fetch API
const fetcher = async (url) => {
  const res = await fetch(url);
  // If the status code is not in the range 200-299,
  // we still try to parse and throw it.
  if (!res.ok) {
    const error = new Error('An error occurred while fetching the data.');
    // Attach extra info to the error object.
    error.info = await res.json();
    error.status = res.status;
    throw error;
  }
  return res.json();
};

function UserProfile({ userId }) {
  // The 'key' is the unique identifier for the data,
  // and 'fetcher' is the function to get the data.
  const { data, error, isLoading } = useSWR(
    userId ? `https://jsonplaceholder.typicode.com/users/${userId}` : null,
    fetcher
  );

  if (isLoading) {
    return <div>Loading user data...</div>;
  }

  if (error) {
    return <div>Failed to load user: {error.message}</div>;
  }

  if (!data) {
    return <div>No user data available.</div>;
  }

  return (
    <div style={{ border: '1px solid #ccc', padding: '15px', borderRadius: '5px', margin: '20px' }}>
      <h2>User Profile</h2>
      <p><strong>Name:</strong> {data.name}</p>
      <p><strong>Username:</strong> {data.username}</p>
      <p><strong>Email:</strong> {data.email}</p>
      <p><strong>Phone:</strong> {data.phone}</p>
      <p><strong>Website:</strong> {data.website}</p>
      <p><strong>Company:</strong> {data.company.name}</p>
    </div>
  );
}

// Example of how to use UserProfile in a parent component
function App() {
  const [userId, setUserId] = React.useState(1);

  return (
    <div>
      <h1>SWR Data Fetching Example</h1>
      <button onClick={() => setUserId(prevId => prevId === 10 ? 1 : prevId + 1)}>
        Next User (Current ID: {userId})
      </button>
      <UserProfile userId={userId} />
      <UserProfile userId={2} /> {/* This component will also fetch user 2 */}
      {/* If userId=1 is already cached by the first component, this one will use the cache */}
      <UserProfile userId={1} />
    </div>
  );
}

export default App;