Nextjs 13: How to show the loading ui when search params changes?

2 min read 05-10-2024
Nextjs 13: How to show the loading ui when search params changes?


Next.js 13: Dynamically Displaying Loading States During Search Param Changes

Ever wished your Next.js 13 application could gracefully handle search parameter changes and display a loading indicator while fetching updated data? This article dives into how to implement a seamless loading UI experience when search parameters change, making your application more user-friendly and visually engaging.

The Scenario

Imagine you have a Next.js 13 application displaying a list of products based on a category search parameter. When the user clicks on a different category, the URL updates with the new search parameter, and the product list should refresh. However, the user might experience a noticeable delay while the data is fetched, which can be frustrating.

Original Code (without loading UI):

"use client";

import { useState, useEffect } from 'react';
import { useSearchParams } from 'next/navigation';

export default function ProductList() {
  const [products, setProducts] = useState([]);
  const [searchParams] = useSearchParams();

  useEffect(() => {
    const category = searchParams.get('category');
    fetch(`/api/products?category=${category}`)
      .then(res => res.json())
      .then(data => setProducts(data))
      .catch(error => console.error(error));
  }, [searchParams]);

  return (
    <div>
      <h1>Products</h1>
      <ul>
        {products.map(product => (
          <li key={product.id}>{product.name}</li>
        ))}
      </ul>
    </div>
  );
}

This code fetches the product data based on the category search parameter, but it lacks a visual indication of the loading process. Let's enhance it with a loading UI.

Adding a Loading UI

We'll introduce a isLoading state to track whether the data is being fetched. We'll also display a loading spinner while isLoading is true and the product list once the data is available.

Updated Code (with loading UI):

"use client";

import { useState, useEffect } from 'react';
import { useSearchParams } from 'next/navigation';

export default function ProductList() {
  const [products, setProducts] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [searchParams] = useSearchParams();

  useEffect(() => {
    setIsLoading(true); // Set isLoading to true when fetching
    const category = searchParams.get('category');
    fetch(`/api/products?category=${category}`)
      .then(res => res.json())
      .then(data => {
        setProducts(data);
        setIsLoading(false); // Set isLoading to false after data is fetched
      })
      .catch(error => console.error(error));
  }, [searchParams]);

  return (
    <div>
      <h1>Products</h1>
      {isLoading ? (
        <div>Loading...</div>
      ) : (
        <ul>
          {products.map(product => (
            <li key={product.id}>{product.name}</li>
          ))}
        </ul>
      )}
    </div>
  );
}

This updated code displays "Loading..." while the data is fetched, providing a visual cue to the user that the application is processing their request.

Additional Considerations

  • Custom Loading Indicators: Replace the simple "Loading..." message with a visually appealing loading spinner or animation for a more polished user experience.
  • Error Handling: Implement error handling mechanisms to display appropriate messages if the data fetching fails.
  • Data Caching: Consider caching the fetched data to improve performance and reduce the number of API requests.
  • Debouncing: If the search parameter changes frequently, introduce a debouncing mechanism to avoid excessive API calls and ensure a smooth loading experience.

By incorporating a loading UI, you significantly improve the user experience, making your Next.js 13 application more responsive and engaging.