article

Monday, January 13, 2025

Nextjs Data fetching using SWR

Nextjs Data fetching using SWR

Install nextjs npx create-next-app@latest https://nextjs.org/docs/getting-started/installation

Install the following

SWR React Hooks for Data Fetching
npm i swr
https://swr.vercel.app/docs/getting-started
app\page.tsx
//app\page.tsx
import Post from "./components/post";

export default function Home() {
  return (
    <div className="max-w-7xl flex flex-col gap-10 mx-auto p-10">
      <div className="flex justify-between items-center">
        <h1 className="text-4xl font-bold">Nextjs Data fetching using SWR</h1>
      </div>
      <Post />
    </div>
  );
}
app\components\post.tsx
//app\components\post.tsx
"use client";

import useSWR from "swr"; //npm i swr https://swr.vercel.app/docs/getting-started

const fetcher = (url) => fetch(url).then((res) => res.json());

export default function Home() {
  const {
    data: posts,
    isLoading,
    isError: error,
  } = useSWR(
    'https://jsonplaceholder.typicode.com/posts',
    fetcher,
    { revalidateOnFocus: false, revalidateOnReconnect: false }
  );

  if (error) {
    return <p className='text-secondary'>Failed to fetch</p>;
  }

  return (
    <>
      <header className='p-7 text-center'>
        <h1 className='text-secondary font-bold text-xl'>Basic</h1>
      </header>
      <main className='max-w-[1100px] mx-auto mt-10 pb-10 px-4'>
        {isLoading ? (
          <p className='text-secondary'>Loading posts</p>
        ) : (
          <ul className='grid grid-cols-3 gap-x-3 gap-y-3'>
            {posts.map((post, index) => (
              <li className='bg-primary p-10 rounded-lg shadow-md border border-gray-200' key={index}>
                <span className='block mb-4 font-bold text-lg text-secondary capitalize'>
                  {post.title}
                </span>
                <span className='text-secondary'>{post.body}</span>
                <h2>{post.id}</h2>
              </li>
            ))}
          </ul>
        )}
      </main>
    </>
  );
}
app\infinite-loading\page.tsx
//app\infinite-loading\page.tsx
"use client";

import useSWRInfinite from 'swr/infinite';

const fetcher = (url) => fetch(url).then((res) => res.json());

const getKey = (pageIndex, previousPageData) => {
  if (pageIndex && !previousPageData.length) return null;
  return `https://jsonplaceholder.typicode.com/posts?_page=${pageIndex}&_limit=6`;
};

export default function Home() {
  const { data, size, setSize, isLoading } = useSWRInfinite(getKey, fetcher);

  return (
    <div className="max-w-7xl flex flex-col gap-10 mx-auto p-10">
      <div className="flex justify-between items-center">
        <h1 className="text-4xl font-bold">Nextjs Data fetching using SWR</h1>
      </div>
      <header className='p-7 text-center'>
        <h1 className='text-secondary font-bold text-xl'>Infinite Loading</h1>
      </header>
      <main className='max-w-[1100px] mx-auto mt-10 pb-10 px-4'>
        {isLoading ? (
          <p className='text-secondary'>Loading posts</p>
        ) : (
          <ul className='grid grid-cols-3 gap-x-3 gap-y-3'>
            {data.map((posts) => {
              return posts.map((post, index) => (
                <li
                  className='bg-primary p-10 rounded-lg shadow-md border border-gray-200'
                  key={index}
                >
                  <span className='block mb-4 font-bold text-lg text-secondary capitalize'>
                    {post.title}
                  </span>
                  <span className='text-secondary'>{post.body}</span>
                </li>
              ));
            })}
          </ul>
        )}
        <div className='max-w-[600px] mx-auto my-10 flex justify-center'>
          <button
            className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
            onClick={() => setSize(size + 1)}
          >
            Load more
          </button>
        </div>
      </main>
    </div>
  );
}
app\prevnext-pagination\page.tsx
//app\prevnext-pagination\page.tsx
"use client";

import { useState } from 'react';
import useSWR from 'swr';

const fetcher = (url) => fetch(url).then((res) => res.json());
const Page = ({ pageIndex }) => {
    const { data: posts, isLoading } = useSWR(
      `https://jsonplaceholder.typicode.com/posts?_page=${pageIndex}&_limit=6`,
      fetcher
    );

  return (
    isLoading ? (
          <p className='text-secondary'>Loading posts</p>
        ) : (
          <ul className='grid grid-cols-3 gap-x-3 gap-y-3'>
            {posts.map((post, index) => (
              <li className='bg-primary p-10 rounded-lg shadow-md border border-gray-200' key={index}>
                <span className='block mb-4 font-bold text-lg text-secondary capitalize'>
                  {post.title}
                </span>
                <span className='text-secondary'>{post.body}</span>
                <h2>{post.id}</h2>
              </li>
            ))}
          </ul>
        )
  )
}

export default function Home() {
  const [pageIndex, setPageIndex] = useState(1);

  return (
    <div className="max-w-7xl flex flex-col gap-10 mx-auto p-10">
      <div className="flex justify-between items-center">
        <h1 className="text-4xl font-bold">Nextjs Data fetching using SWR</h1>
      </div>
      <header className="p-7 text-center">
        <h1 className="text-secondary font-bold text-xl">Next Prev Pagination</h1>
      </header>
      <main className="max-w-[1100px] mx-auto mt-10 pb-10 px-4">
        <Page pageIndex={pageIndex} />
        <div className="hidden">
          <Page pageIndex={pageIndex + 1} />
        </div>
        <div className="max-w-[600px] mx-auto my-10 grid grid-cols-2 gap-x-3">
          <button
            className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
            onClick={() => setPageIndex((_currentPage) => _currentPage - 1)}
          >
            Prev
          </button>
          <button
            className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
            onClick={() => setPageIndex((_currentPage) => _currentPage + 1)}
          >
            Next
          </button>
        </div>
      </main>
    </div>
  );
}
run C:\nextjs>npm run dev

Related Post