دریافت داده در Next.js – کامپوننت‌های سروری، کلاینتی، استریمینگ و کش هوشمند

در Next.js می‌توان داده‌ها را در کامپوننت‌های سروری و کلاینتی دریافت کرد. این مقاله روش‌های دریافت داده با fetch، ORM، هوک use، کتابخانه‌هایی مانند SWR، و تکنیک‌های استریمینگ با Suspense و فایل loading.tsx را بررسی می‌کند. همچنین با مکانیزم کش داخلی و بهینه‌سازی درخواست‌ها آشنا می‌شویم.

data fetchingServer Componentstreaminguse hook

~4 دقیقه مطالعه • بروزرسانی ۳ آبان ۱۴۰۴

دریافت داده در کامپوننت‌های سروری


در کامپوننت‌های سروری می‌توان داده‌ها را با استفاده از API fetch یا پایگاه داده دریافت کرد. کافی است کامپوننت را به تابع async تبدیل کرده و داده را await کنید:


مثال با fetch


// app/blog/page.tsx
export default async function Page() {
  const data = await fetch('https://api.vercel.app/blog')
  const posts = await data.json()
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

مثال با پایگاه داده


// app/blog/page.tsx
import { db, posts } from '@/lib/db'

export default async function Page() {
  const allPosts = await db.select().from(posts)
  return (
    <ul>
      {allPosts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

دریافت داده در کامپوننت‌های کلاینتی


در کامپوننت‌های کلاینتی می‌توان از هوک use یا کتابخانه‌هایی مانند SWR و React Query استفاده کرد.


استریمینگ با use


ابتدا داده را در کامپوننت سروری دریافت کرده و پرامیس را به کامپوننت کلاینتی ارسال کنید:


// app/blog/page.tsx
import Posts from '@/app/ui/posts'
import { Suspense } from 'react'

export default function Page() {
  const posts = getPosts()
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Posts posts={posts} />
    </Suspense>
  )
}

سپس در کامپوننت کلاینتی از هوک use برای خواندن پرامیس استفاده کنید:


// app/ui/posts.tsx
'use client'
import { use } from 'react'

export default function Posts({ posts }) {
  const allPosts = use(posts)
  return (
    <ul>
      {allPosts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

استفاده از SWR


// app/blog/page.tsx
'use client'
import useSWR from 'swr'

const fetcher = (url) => fetch(url).then((r) => r.json())

export default function BlogPage() {
  const { data, error, isLoading } = useSWR(
    'https://api.vercel.app/blog',
    fetcher
  )

  if (isLoading) return <div>Loading...</div>
  if (error) return <div>Error: {error.message}</div>

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

بهینه‌سازی درخواست‌ها و کش داده


  • درخواست‌های GET/HEAD مشابه در یک render pass به‌صورت خودکار deduplicate می‌شوند
  • استفاده از cache: 'force-cache' در fetch باعث کش شدن داده‌ها در Data Cache می‌شود
  • برای ORM یا پایگاه داده، می‌توان از تابع cache در React استفاده کرد:

// app/lib/data.ts
import { cache } from 'react'
import { db, posts, eq } from '@/lib/db'

export const getPost = cache(async (id: string) => {
  const post = await db.query.posts.findFirst({
    where: eq(posts.id, parseInt(id)),
  })
})

استریمینگ در Next.js


با فعال بودن cacheComponents، می‌توان از استریمینگ برای ارسال بخش‌های HTML به‌صورت تدریجی استفاده کرد.


استفاده از loading.tsx


در پوشهٔ مسیر، فایل loading.tsx اضافه کنید تا هنگام دریافت داده، رابط بارگذاری نمایش داده شود:


// app/blog/loading.tsx
export default function Loading() {
  return <div>Loading...</div>
}

استفاده از Suspense برای استریم جزئی


// app/blog/page.tsx
import { Suspense } from 'react'
import BlogList from '@/components/BlogList'
import BlogListSkeleton from '@/components/BlogListSkeleton'

export default function BlogPage() {
  return (
    <div>
      <header>
        <h1>Welcome to the Blog</h1>
        <p>Read the latest posts below.</p>
      </header>
      <main>
        <Suspense fallback={<BlogListSkeleton />}>
          <BlogList />
        </Suspense>
      </main>
    </div>
  )
}

جمع‌بندی


Next.js ابزارهای قدرتمندی برای دریافت داده در کامپوننت‌های سروری و کلاینتی ارائه می‌دهد. با استفاده از هوک‌ها، کتابخانه‌های جامعه‌محور، کش هوشمند و استریمینگ، می‌توان رابط‌هایی سریع، پویا و قابل نگهداری ساخت.


نوشته و پژوهش شده توسط دکتر شاهین صیامی