كيفية تحديث البيانات

يمكنك تحديث البيانات في Next.js باستخدام وظائف الخادم (Server Functions) الخاصة بـ React. ستوضح هذه الصفحة كيفية إنشاء واستدعاء وظائف الخادم.

وظائف الخادم

وظيفة الخادم هي وظيفة غير متزامنة يتم تنفيذها على الخادم. وظائف الخادم غير متزامنة بطبيعتها لأنها تُستدعى من قبل العميل باستخدام طلب شبكة. عند استدعائها كجزء من action، تُسمى أيضًا إجراءات الخادم (Server Actions).

بشكل اصطلاحي، action هي وظيفة غير متزامنة يتم تمريرها إلى startTransition. يتم تغليف وظائف الخادم تلقائيًا بـ startTransition عندما:

  • يتم تمريرها إلى <form> باستخدام خاصية action
  • يتم تمريرها إلى <button> باستخدام خاصية formAction
  • يتم تمريرها إلى useActionState

إنشاء وظائف الخادم

يمكن تعريف وظيفة الخادم باستخدام توجيه use server. يمكنك وضع التوجيه في أعلى وظيفة غير متزامنة لوضع علامة على الوظيفة كوظيفة خادم، أو في أعلى ملف منفصل لوضع علامة على جميع الصادرات من ذلك الملف.

export async function createPost(formData: FormData) {
  'use server'
  const title = formData.get('title')
  const content = formData.get('content')

  // تحديث البيانات
  // إعادة التحقق من صحة الذاكرة المؤقتة
}

export async function deletePost(formData: FormData) {
  'use server'
  const id = formData.get('id')

  // تحديث البيانات
  // إعادة التحقق من صحة الذاكرة المؤقتة
}
export async function createPost(formData) {
  'use server'
  const title = formData.get('title')
  const content = formData.get('content')

  // تحديث البيانات
  // إعادة التحقق من صحة الذاكرة المؤقتة
}

export async function deletePost(formData) {
  'use server'
  const id = formData.get('id')

  // تحديث البيانات
  // إعادة التحقق من صحة الذاكرة المؤقتة
}

مكونات الخادم

يمكن تضمين وظائف الخادم في مكونات الخادم عن طريق إضافة توجيه "use server" في أعلى جسم الوظيفة:

export default function Page() {
  // إجراء الخادم
  async function createPost(formData: FormData) {
    'use server'
    // ...
  }

  return <></>
}
export default function Page() {
  // إجراء الخادم
  async function createPost(formData: FormData) {
    'use server'
    // ...
  }

  return <></>
}

مكونات العميل

لا يمكن تعريف وظائف الخادم في مكونات العميل. ومع ذلك، يمكنك استدعاؤها في مكونات العميل عن طريق استيرادها من ملف يحتوي على توجيه "use server" في أعلى الملف:

'use server'

export async function createPost() {}
'use server'

export async function createPost() {}
'use client'

import { createPost } from '@/app/actions'

export function Button() {
  return <button formAction={createPost}>إنشاء</button>
}
'use client'

import { createPost } from '@/app/actions'

export function Button() {
  return <button formAction={createPost}>إنشاء</button>
}

استدعاء وظائف الخادم

هناك طريقتان رئيسيتان لاستدعاء وظيفة الخادم:

  1. النماذج (Forms) في مكونات الخادم والعميل
  2. معالجو الأحداث (Event Handlers) في مكونات العميل

النماذج

يمتد React لعنصر <form> في HTML للسماح باستدعاء وظيفة الخادم باستخدام خاصية action في HTML.

عند استدعائها في نموذج، تتلقى الوظيفة تلقائيًا كائن FormData. يمكنك استخراج البيانات باستخدام طرق FormData الأصلية:

import { createPost } from '@/app/actions'

export function Form() {
  return (
    <form action={createPost}>
      <input type="text" name="title" />
      <input type="text" name="content" />
      <button type="submit">إنشاء</button>
    </form>
  )
}
import { createPost } from '@/app/actions'

export function Form() {
  return (
    <form action={createPost}>
      <input type="text" name="title" />
      <input type="text" name="content" />
      <button type="submit">إنشاء</button>
    </form>
  )
}
'use server'

export async function createPost(formData: FormData) {
  const title = formData.get('title')
  const content = formData.get('content')

  // تحديث البيانات
  // إعادة التحقق من صحة الذاكرة المؤقتة
}
'use server'

export async function createPost(formData) {
  const title = formData.get('title')
  const content = formData.get('content')

  // تحديث البيانات
  // إعادة التحقق من صحة الذاكرة المؤقتة
}

معلومة مفيدة: عند تمريرها إلى خاصية action، تُعرف وظائف الخادم أيضًا باسم إجراءات الخادم (Server Actions).

معالجو الأحداث

يمكنك استدعاء وظيفة الخادم في مكون العميل باستخدام معالجي الأحداث مثل onClick.

'use client'

import { incrementLike } from './actions'
import { useState } from 'react'

export default function LikeButton({ initialLikes }: { initialLikes: number }) {
  const [likes, setLikes] = useState(initialLikes)

  return (
    <>
      <p>إجمالي الإعجابات: {likes}</p>
      <button
        onClick={async () => {
          const updatedLikes = await incrementLike()
          setLikes(updatedLikes)
        }}
      >
        إعجاب
      </button>
    </>
  )
}
'use client'

import { incrementLike } from './actions'
import { useState } from 'react'

export default function LikeButton({ initialLikes }) {
  const [likes, setLikes] = useState(initialLikes)

  return (
    <>
      <p>إجمالي الإعجابات: {likes}</p>
      <button
        onClick={async () => {
          const updatedLikes = await incrementLike()
          setLikes(updatedLikes)
        }}
      >
        إعجاب
      </button>
    </>
  )
}

أمثلة

عرض حالة الانتظار

أثناء تنفيذ وظيفة الخادم، يمكنك عرض مؤشر تحميل باستخدام خطاف useActionState الخاص بـ React. يُرجع هذا الخطاف قيمة منطقية pending:

'use client'

import { useActionState, startTransition } from 'react'
import { createPost } from '@/app/actions'
import { LoadingSpinner } from '@/app/ui/loading-spinner'

export function Button() {
  const [state, action, pending] = useActionState(createPost, false)

  return (
    <button onClick={() => startTransition(action)}>
      {pending ? <LoadingSpinner /> : 'إنشاء منشور'}
    </button>
  )
}
'use client'

import { useActionState, startTransition } from 'react'
import { createPost } from '@/app/actions'
import { LoadingSpinner } from '@/app/ui/loading-spinner'

export function Button() {
  const [state, action, pending] = useActionState(createPost, false)

  return (
    <button onClick={() => startTransition(action)}>
      {pending ? <LoadingSpinner /> : 'إنشاء منشور'}
    </button>
  )
}

إعادة التحقق من صحة الذاكرة المؤقتة

بعد إجراء تحديث، يمكنك إعادة التحقق من صحة ذاكرة Next.js المؤقتة وعرض البيانات المحدثة عن طريق استدعاء revalidatePath أو revalidateTag داخل وظيفة الخادم:

import { revalidatePath } from 'next/cache'

export async function createPost(formData: FormData) {
  'use server'
  // تحديث البيانات
  // ...

  revalidatePath('/posts')
}
import { revalidatePath } from 'next/cache'

export async function createPost(formData) {
  'use server'
  // تحديث البيانات
  // ...
  revalidatePath('/posts')
}

إعادة التوجيه

قد ترغب في إعادة توجيه المستخدم إلى صفحة مختلفة بعد إجراء تحديث. يمكنك القيام بذلك عن طريق استدعاء redirect داخل وظيفة الخادم:

'use server'

import { redirect } from 'next/navigation'

export async function createPost(formData: FormData) {
  // تحديث البيانات
  // ...

  redirect('/posts')
}
'use server'

import { redirect } from 'next/navigation'

export async function createPost(formData) {
  // تحديث البيانات
  // ...

  redirect('/posts')
}