الداتا · فصل ٦

الـ loader قبل ما الصفحة تبان

loader · useLoaderData · pending · error
🎯 الهدف: تجيب البوست قبل الرسم، وتعرض انتظار وخطأ من غير useEffect.

الـ loader بيشتغل قبل ما الكومبوننت يترسم. الداتا تبقى جاهزة، من غير حالة تحميل تكتبها بإيدك جوه useEffect.

src/routes/posts/$postId.tsx
import { createFileRoute } from "@tanstack/react-router";export const Route = createFileRoute("/posts/$postId")({  loader: async ({ params }) => {    const res = await fetch(      `https://jsonplaceholder.typicode.com/posts/${params.postId}`,    );    if (!res.ok) throw new Error("Post not found");    return res.json();  },  pendingComponent: () => <p>جاري التحميل...</p>,  errorComponent: ({ error }) => <p>حصل خطأ: {error.message}</p>,  component: PostPage,});function PostPage() {  const post = Route.useLoaderData();  return (    <div>      <h1>{post.title}</h1>      <p>{post.body}</p>    </div>  );}

useEffect بيحصل بعد الرسم، فتشوف «جاري التحميل» كوميض، وبتكتب حالة الخطأ بإيدك، ومفيش كاش جاهز. الـ loader بيحصل قبل الظهور، وفيه كومبوننت انتظار وكومبوننت خطأ، وكاش قريب من فكرة React Query.

useEffect

بعد الرسم. وميض تحميل. الحالة إنت اللي تكتبها.

loader

قبل الظهور. انتظار وخطأ جاهزين على الراوت. فيه كاش.

اللي بعد كده في المكتبة، لما تحب تكمّل من الدوكس: حماية الراوت قبل التحميل، والفرق بين قراءة المعاملات من الراوت ومن هوك عام، وصفحة مش موجودة.

خلّصت الفصل لما

🧠 اختبر نفسك
١) ليه الـ loader أقل وميض من useEffect؟
لأنه بيخلّص قبل ما الصفحة تتفتح، مش بعد أول رسم.
٢) الطلب فشل. مين يعرض الرسالة؟
errorComponent على الراوت، مش حالة تكتبها جوه الصفحة.
٣) الداتا جاهزة تتقرأ بإيه؟
Route.useLoaderData.