React 19 Server Components: What Changed and Why

Deep dive into React 19 Server Components: Actions, use() hook, asset loading, optimistic updates, and the architectural patterns that make RSC production-ready.

E
ECOSIRE Research and Development Team
|19 मार्च 202611 मिनट पढ़ें2.5k शब्द|

हमारी Performance & Scalability श्रृंखला का हिस्सा

पूरी गाइड पढ़ें

रिएक्ट 19 सर्वर घटक: क्या बदला और क्यों

हुक्स के बाद रिएक्ट 19 सबसे महत्वपूर्ण रिलीज़ है। सर्वर घटक, जो रिएक्ट 18 में एक प्रायोगिक सुविधा के रूप में शुरू हुए थे, अब स्थिर हैं और समवर्ती रेंडरिंग मॉडल के साथ पूरी तरह से एकीकृत हैं। लेकिन परिवर्तन केवल आरएससी को स्थिर करने से कहीं आगे जाते हैं - रिएक्ट 19 एक्शन, एक नया use() हुक, फॉर्म एकीकरण, आशावादी अपडेट और दस्तावेज़ मेटाडेटा प्रबंधन पेश करता है जो सामूहिक रूप से रिएक्ट अनुप्रयोगों में डेटा प्रवाह के बारे में आपके सोचने के तरीके को बदल देता है।

यह मार्गदर्शिका इस बात पर ध्यान केंद्रित करती है कि रिएक्ट 18 और 19 के बीच वास्तव में क्या बदलाव आया है, प्रत्येक परिवर्तन के पीछे के वास्तुशिल्प तर्क को समझाता है, और पुराने दृष्टिकोणों को बदलने वाले उत्पादन पैटर्न को दिखाता है।

मुख्य बातें

  • सर्वर घटक केवल सर्वर पर चलते हैं - उनका कोई जीवनचक्र, कोई स्थिति और कोई ब्राउज़र एपीआई नहीं होता है
  • वादों और संदर्भों का उपभोग करने के लिए use() हुक क्लाइंट घटकों में await को प्रतिस्थापित करता है
  • रिएक्ट 19 क्रियाएँ फॉर्म सबमिशन के लिए मैन्युअल useState + fetch पैटर्न को प्रतिस्थापित करती हैं
  • useOptimistic सर्वर पुष्टिकरण से पहले तत्काल यूआई अपडेट सक्षम करता है
  • useFormStatus आपको फॉर्म घटकों के माध्यम से प्रोप ड्रिलिंग के बिना लंबित स्थिति देता है
  • एसेट प्रीलोडिंग एपीआई (preload, preinit) आपको घटकों से संसाधन लोडिंग को नियंत्रित करने देता है
  • घटकों में <title>, <meta>, और <link> टैग स्वचालित रूप से <head> पर लहराते हैं
  • सर्वर घटक और क्लाइंट घटक एक वृक्ष बनाते हैं - क्लाइंट घटक सर्वर घटकों को आयात नहीं कर सकते

सर्वर घटक वास्तव में क्या हैं

क्या परिवर्तन हुआ इस पर चर्चा करने से पहले, स्पष्ट करें कि सर्वर घटक क्या हैं: रिएक्ट घटक जो विशेष रूप से सर्वर पर प्रस्तुत होते हैं और HTML + RSC पेलोड का उत्पादन करते हैं जिसे क्लाइंट हाइड्रेट करता है। वे सर्वर-साइड रेंडर किए गए क्लाइंट घटकों के समान नहीं हैं।

मुख्य अंतर:

सर्वर घटकग्राहक घटक
चलता हैकेवल सर्वरसर्वर (प्रारंभिक रेंडर) + क्लाइंट
हुक का उपयोग कर सकते हैंनहींहाँ
ब्राउज़र एपीआई का उपयोग कर सकते हैंनहींहाँ
डेटाबेस तक पहुंच सकते हैंहाँ (सीधे)नहीं (एपीआई के माध्यम से)
बंडल आकार प्रभावशून्यहाँ
एसिंक हो सकता हैहाँनहीं (बिना सस्पेंस के)
// Server Component — async, no hooks, direct DB access
async function UserProfile({ userId }: { userId: string }) {
  // Direct database query — no API needed
  const user = await db.query.users.findFirst({
    where: eq(users.id, userId),
  });

  return (
    <div>
      <h1>{user.name}</h1>
      {/* Client Component gets data as props */}
      <UserActions userId={user.id} role={user.role} />
    </div>
  );
}
// Client Component — can use hooks, handles interactions
'use client';

function UserActions({ userId, role }: { userId: string; role: string }) {
  const [isEditing, setIsEditing] = useState(false);

  return (
    <div>
      <button onClick={() => setIsEditing(true)}>Edit</button>
      {isEditing && <EditUserForm userId={userId} />}
    </div>
  );
}

प्रतिक्रिया 19 क्रियाएँ

रिएक्ट 19 में सबसे बड़ा एर्गोनोमिक सुधार एक्शन है - उपयोगकर्ता इंटरैक्शन, विशेष रूप से फॉर्म सबमिशन द्वारा ट्रिगर किए गए एसिंक ऑपरेशंस को संभालने का एक मानकीकृत तरीका।

रिएक्ट 19 से पहले, फॉर्म हैंडलिंग दोहरावदार बॉयलरप्लेट थी:

// React 18 — manual state management
function ContactForm() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setSubmitting(true);
    setError(null);

    try {
      await createContact({ name, email });
    } catch (err) {
      setError(err.message);
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      {/* ... */}
    </form>
  );
}

रिएक्ट 19 क्रियाएँ इसे महत्वपूर्ण रूप से सुव्यवस्थित करती हैं:

// React 19 — useActionState
'use client';

import { useActionState } from 'react';

async function createContactAction(
  prevState: { error?: string },
  formData: FormData
) {
  'use server'; // Server Action — runs on the server

  const name = formData.get('name') as string;
  const email = formData.get('email') as string;

  try {
    await createContact({ name, email });
    return { success: true };
  } catch (err) {
    return { error: err.message };
  }
}

function ContactForm() {
  const [state, formAction, isPending] = useActionState(
    createContactAction,
    {}
  );

  return (
    <form action={formAction}>
      <input name="name" required />
      <input name="email" type="email" required />
      {state.error && <p className="text-red-500">{state.error}</p>}
      <button type="submit" disabled={isPending}>
        {isPending ? 'Submitting...' : 'Submit'}
      </button>
    </form>
  );
}

useActionState हुक लंबित स्थिति, प्रपत्र डेटा और त्रुटि प्रबंधन को एक ही स्थान पर प्रबंधित करता है। एक्शन फ़ंक्शन पर 'use server' निर्देश इसे सर्वर एक्शन के रूप में चिह्नित करता है - यह सर्वर पर चलता है, सीधे डेटाबेस तक पहुंच सकता है, और क्लाइंट कभी भी कार्यान्वयन नहीं देखता है।


सर्वर क्रियाएँ

सर्वर क्रियाएँ 'use server' निर्देश के साथ एसिंक फ़ंक्शंस हैं जो क्लाइंट द्वारा कॉल किए जाने पर सर्वर पर चलती हैं। वे अधिकांश डेटा उत्परिवर्तन उपयोग मामलों के लिए एपीआई मार्गों को प्रतिस्थापित करते हैं:

// app/actions/contacts.ts
'use server';

import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import { db } from '@ecosire/db';
import { contacts } from '@ecosire/db/schema';

export async function createContact(formData: FormData) {
  const name = formData.get('name') as string;
  const email = formData.get('email') as string;

  if (!name || !email) {
    throw new Error('Name and email are required');
  }

  await db.insert(contacts).values({
    name,
    email,
    organizationId: await getOrganizationId(), // From session
  });

  revalidatePath('/dashboard/contacts'); // Invalidate cached page
  redirect('/dashboard/contacts'); // Redirect after success
}

सर्वर क्रियाओं का उपयोग सीधे form तत्वों में किया जा सकता है:

import { createContact } from '@/app/actions/contacts';

export default function NewContactPage() {
  return (
    <form action={createContact}>
      <input name="name" placeholder="Name" required />
      <input name="email" placeholder="Email" type="email" required />
      <button type="submit">Create Contact</button>
    </form>
  );
}

कोई onSubmit हैंडलर नहीं, कोई preventDefault() नहीं, कोई मैनुअल fetch() नहीं - फॉर्म बस काम करता है।


उपयोग() हुक

रिएक्ट 19 रेंडर के अंदर संसाधनों (वादे और संदर्भ) का उपभोग करने के लिए use() हुक पेश करता है। await के विपरीत, यह रिएक्ट के सस्पेंस सिस्टम के साथ काम करता है:

// Before React 19 — had to resolve at the top level
export default async function Page() {
  const posts = await getPosts(); // Blocks entire page
  return <PostList posts={posts} />;
}
// React 19 — pass a promise, resolve with use()
export default function Page() {
  const postsPromise = getPosts(); // Start fetch immediately

  return (
    <Suspense fallback={<PostsSkeleton />}>
      <PostList postsPromise={postsPromise} />
    </Suspense>
  );
}

// Client Component using use() to consume the promise
'use client';

function PostList({ postsPromise }: { postsPromise: Promise<Post[]> }) {
  const posts = use(postsPromise); // Suspends until resolved

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

use() हुक useContext() को भी प्रतिस्थापित करता है - यह सशर्त रूप से संदर्भ का उपभोग कर सकता है (हुक के विपरीत, use() को अंदर की स्थिति और लूप कहा जा सकता है):

'use client';

import { use } from 'react';
import { ThemeContext } from '@/contexts/theme';

function Button({ children }: { children: React.ReactNode }) {
  const theme = use(ThemeContext); // Can be inside conditions

  return (
    <button className={theme === 'dark' ? 'bg-gray-800' : 'bg-white'}>
      {children}
    </button>
  );
}

आशावादी उपयोग के साथ आशावादी अपडेट

useOptimistic सर्वर ऑपरेशन पूरा होने से पहले तत्काल यूआई फीडबैक प्रदान करता है, यदि ऑपरेशन विफल हो जाता है तो स्वचालित रूप से वापस आ जाता है:

'use client';

import { useOptimistic, useTransition } from 'react';

interface Like {
  id: string;
  count: number;
  userLiked: boolean;
}

function LikeButton({ postId, initialLikes }: { postId: string; initialLikes: Like }) {
  const [likes, setOptimisticLikes] = useOptimistic(
    initialLikes,
    (state, action: 'like' | 'unlike') => ({
      ...state,
      count: action === 'like' ? state.count + 1 : state.count - 1,
      userLiked: action === 'like',
    })
  );

  const [isPending, startTransition] = useTransition();

  async function toggleLike() {
    const action = likes.userLiked ? 'unlike' : 'like';

    startTransition(async () => {
      setOptimisticLikes(action); // Instant UI update

      // Server operation — if this fails, optimistic state reverts
      await togglePostLike(postId, action);
    });
  }

  return (
    <button onClick={toggleLike} disabled={isPending}>
      {likes.userLiked ? '♥' : '♡'} {likes.count}
    </button>
  );
}

आशावादी अद्यतन तुरंत दिखाई देता है, फिर या तो चालू हो जाता है (सर्वर सफलता) या वापस आ जाता है (सर्वर विफलता)। उपयोगकर्ताओं को नेटवर्क राउंड-ट्रिप की प्रतीक्षा किए बिना तुरंत प्रतिक्रिया मिलती है।


घटकों से दस्तावेज़ मेटाडेटा

रिएक्ट 19 <title>, <meta>, और <link> टैग को किसी भी घटक के अंदर प्रस्तुत करने की अनुमति देता है - वे स्वचालित रूप से दस्तावेज़ <head> पर लहराते हैं:

// Server Component — metadata hoists to <head> automatically
async function BlogPost({ slug }: { slug: string }) {
  const post = await getPost(slug);

  return (
    <article>
      <title>{post.title}</title>
      <meta name="description" content={post.description} />
      <link rel="canonical" href={`https://ecosire.com/blog/${slug}`} />

      <h1>{post.title}</h1>
      <div>{post.content}</div>
    </article>
  );
}

यह सर्वर और क्लाइंट कंपोनेंट दोनों में काम करता है। Next.js जैसे फ्रेमवर्क में, आप अभी भी OpenGraph टैग और hreflang विशेषताओं पर पूर्ण नियंत्रण के लिए generateMetadata() का उपयोग करेंगे - रिएक्ट 19 का मूल समर्थन अधिक बुनियादी है। लेकिन साधारण मामलों के लिए, यह next/head या समान पुस्तकालयों की आवश्यकता को समाप्त कर देता है।


एसेट लोडिंग एपीआई

रिएक्ट 19 संसाधनों को प्रीलोड करने के लिए स्पष्ट एपीआई प्रदान करता है, जिससे आपको संसाधन लोडिंग वॉटरफॉल पर बेहतर नियंत्रण मिलता है:

import { preload, preinit, prefetchDNS, preconnect } from 'react-dom';

function BelowFoldSection() {
  // When this component renders, preload the hero image for next section
  preload('/images/hero-next.webp', { as: 'image' });

  // Preinit a script (loads and executes immediately)
  preinit('https://cdn.example.com/analytics.js', { as: 'script' });

  // DNS prefetch for external resources
  prefetchDNS('https://fonts.googleapis.com');

  // Establish connection early
  preconnect('https://api.ecosire.com');

  return <section>{/* content */}</section>;
}

ये एपीआई रिएक्ट के रेंडरिंग मॉडल के साथ सही ढंग से काम करते हैं - वे संसाधन संकेतों को बैच करते हैं और उन्हें दस्तावेज़ में इष्टतम बिंदु पर उत्सर्जित करते हैं, यहां तक ​​कि घटक पेड़ की गहराई से भी।


सामान्य नुकसान और समाधान

नुकसान 1: सर्वर घटकों में हुक का उपयोग करने का प्रयास

सर्वर घटक useState, useEffect, useContext, या किसी अन्य हुक का उपयोग नहीं कर सकते। यदि आपको इनकी आवश्यकता है, तो घटक में 'use client' जोड़ें। त्रुटि आमतौर पर होती है: Error: Hooks can only be called inside a function component.

नुकसान 2: क्लाइंट घटकों से सर्वर घटकों को आयात करना

क्लाइंट घटक सर्वर घटकों को आयात नहीं कर सकते (इसके विपरीत ठीक है)। ऐसा इसलिए है क्योंकि क्लाइंट घटक उस ब्राउज़र में चलते हैं जहां सर्वर घटक मौजूद नहीं हैं। यदि आपको उन्हें लिखने की आवश्यकता है, तो सर्वर घटकों को children प्रॉप्स के रूप में पास करें:

// Wrong — Client Component cannot import Server Component
'use client';
import { ServerUserProfile } from './server-user-profile'; // Error

// Correct — pass as children from a Server Component parent
// Parent (Server):
<ClientShell>
  <ServerUserProfile userId={userId} />
</ClientShell>

// ClientShell:
'use client';
function ClientShell({ children }: { children: React.ReactNode }) {
  return <div className="shell">{children}</div>;
}

नुकसान 3: सर्वर से क्लाइंट तक प्रॉप्स पास करते समय क्रमांकन त्रुटियाँ

केवल JSON-क्रमबद्ध डेटा ही प्रॉप्स के रूप में सर्वर-क्लाइंट सीमा को पार कर सकता है। फ़ंक्शंस, क्लास इंस्टेंसेस, मैप, सेट और दिनांक (ऑब्जेक्ट्स के रूप में) को क्रमबद्ध नहीं किया जा सकता है। दिनांकों को ISO स्ट्रिंग में कनवर्ट करें; फ़ंक्शंस को स्ट्रिंग पहचानकर्ताओं से बदलें।

नुकसान 4: सर्वर क्रियाएँ इनपुट को मान्य नहीं कर रही हैं

सर्वर क्रियाओं में क्लाइंट द्वारा प्रदत्त डेटा पर कभी भरोसा न करें। डेटाबेस पर लिखने से पहले हमेशा ज़ॉड या इसके समान सत्यापन करें:

'use server';

import { z } from 'zod';

const schema = z.object({
  name: z.string().min(2).max(255),
  email: z.string().email(),
});

export async function createContact(formData: FormData) {
  const result = schema.safeParse({
    name: formData.get('name'),
    email: formData.get('email'),
  });

  if (!result.success) {
    return { error: result.error.flatten().fieldErrors };
  }

  await db.insert(contacts).values(result.data);
}

अक्सर पूछे जाने वाले प्रश्न

क्या सर्वर घटक Next.js के बाहर उपलब्ध हैं?

रिएक्ट सर्वर कंपोनेंट्स एक रिएक्ट फीचर हैं, लेकिन उन्हें सर्वर रेंडरिंग इंफ्रास्ट्रक्चर - रूटिंग, बंडलिंग, स्ट्रीमिंग को संभालने के लिए एक फ्रेमवर्क की आवश्यकता होती है। Next.js ऐप राउटर सबसे परिपक्व कार्यान्वयन है। रीमिक्स, एस्ट्रो और वाइट-आधारित सेटअप आरएससी समर्थन जोड़ रहे हैं। फ्रेमवर्क के बिना आरएससी का उपयोग करने के लिए महत्वपूर्ण कस्टम इंफ्रास्ट्रक्चर कार्य की आवश्यकता होती है।

सर्वर क्रियाएँ REST API मार्गों से तुलना कैसे करती हैं?

यूआई से जुड़े म्यूटेशन के लिए सर्वर क्रियाएं सरल हैं - प्रबंधित करने के लिए कोई एंडपॉइंट यूआरएल नहीं, लिखने के लिए कोई fetch() कॉल नहीं, बॉयलरप्लेट को संभालने में कोई त्रुटि नहीं। REST API रूट वेब ऐप (मोबाइल ऐप, वेबहुक, थर्ड-पार्टी इंटीग्रेशन) के बाहर से बुलाए गए संचालन के लिए बेहतर हैं, सार्वजनिक एपीआई के लिए जिन्हें दस्तावेज़ीकरण की आवश्यकता होती है, और जब आपको स्पष्ट HTTP स्थिति कोड की आवश्यकता होती है। उपयोग के मामले के आधार पर एक ही एप्लिकेशन में दोनों का उपयोग करें।

सर्वर घटकों के प्रदर्शन पर क्या प्रभाव पड़ता है?

सर्वर घटक जावास्क्रिप्ट बंडल आकार को कम करते हैं (घटक कोड कभी भी ब्राउज़र पर नहीं भेजा जाता है), क्लाइंट-साइड डेटा प्राप्त करने वाले झरनों को खत्म करते हैं, और सस्पेंस के माध्यम से स्ट्रीमिंग HTML डिलीवरी को सक्षम करते हैं। ट्रेडऑफ़ सर्वर गणना लागत है - रेंडरिंग आपके सर्वर पर होती है, क्लाइंट के डिवाइस पर नहीं। डेटा-भारी पृष्ठों के लिए, यह लगभग हमेशा एक शुद्ध जीत है।

क्या मैं रिएक्ट 18 और रिएक्ट 19 को एक कोडबेस में मिला सकता हूँ?

सभी रिएक्ट कोड रिएक्ट 19 के रूप में चलते हैं - कोई प्रति-फ़ाइल संस्करण नहीं है। सवाल यह है कि क्या आपका मौजूदा रिएक्ट 18 कोड रिएक्ट 19 में काम करता है। अधिकांश रिएक्ट 18 कोड अपरिवर्तित काम करता है। मुख्य ब्रेकिंग परिवर्तन refs (अब एक नियमित प्रोप), ReactDOM.render निष्कासन, और @types/react में कुछ टाइपिंग परिवर्तन के आसपास हैं। स्वचालित माइग्रेशन के लिए रिएक्ट 19 कोडमोड चलाएँ।

मैं सर्वर घटकों का परीक्षण कैसे करूं?

सर्वर घटकों का परीक्षण async render का उपयोग करके रिएक्ट टेस्टिंग लाइब्रेरी के साथ किया जा सकता है। सर्वर क्रियाओं के लिए, उन्हें नकली डेटाबेस कॉल के साथ सादे एसिंक फ़ंक्शंस के रूप में परीक्षण करें। प्लेराइट के साथ एंड-टू-एंड परीक्षण बिना किसी विशेष सेटअप के पूर्ण सर्वर घटक + क्लाइंट घटक एकीकरण को कवर करते हैं - वे अंतिम HTML आउटपुट का परीक्षण करते हैं।


अगले चरण

रिएक्ट 19 सर्वर घटक आधुनिक वेब अनुप्रयोगों के निर्माण में एक मूलभूत बदलाव का प्रतिनिधित्व करते हैं। ECOSIRE की फ्रंटएंड टीम ने इस आर्किटेक्चर पर उत्पादन एप्लिकेशन बनाए हैं - सर्वर घटकों, सर्वर क्रियाओं और वास्तविक उपयोगकर्ता वर्कफ़्लो को सशक्त बनाने वाले आशावादी अपडेट के साथ 249 पृष्ठ।

यदि आपको रिएक्ट 18 से 19 में माइग्रेट करने, एक नया आरएससी-प्रथम एप्लिकेशन तैयार करने में सहायता की आवश्यकता है, या बस अपनी टीम में विशेषज्ञ फ्रंटएंड इंजीनियरिंग चाहते हैं, हमारी विकास सेवाओं का पता लगाएं

शेयर करें:
E

लेखक

ECOSIRE Research and Development Team

ECOSIRE में एंटरप्राइज़-ग्रेड डिजिटल उत्पाद बना रहे हैं। Odoo एकीकरण, ई-कॉमर्स ऑटोमेशन, और AI-संचालित व्यावसायिक समाधानों पर अंतर्दृष्टि साझा कर रहे हैं।

WhatsApp पर चैट करें