📚 بخش 15: ارسال Props به کامپوننت‌ها

""

۱. مقدمه — چرا Props قلب ارتباط در React است؟

در React، ما UI را به واحدهای کوچک و قابل‌مدیری به نام کامپوننت تقسیم می‌کنیم.
این کار باعث می‌شود:

  • کد تمیزتر و قابل نگهداری باشد.
  • امکان استفاده مجدد فراهم شود.
  • تغییرات محدود به بخش‌های کوچک باشد.

اما یک مشکل بزرگ پیش می‌آید…
اگر یک کامپوننت همیشه خروجی یکسانی داشته باشد، در عمل بی‌فایده می‌شود.
به عنوان مثال:

function Header() {
  return <h1>صفحه اصلی</h1>;
}

این Header همیشه متن “صفحه اصلی” را برمی‌گرداند.
اما اگر بخواهیم این هدر را در ۱۰ صفحه مختلف استفاده کنیم و عنوان هر صفحه فرق داشته باشد، چطور؟ 🤔

اینجاست که props وارد عمل می‌شود.
Props به ما این امکان را می‌دهد که داده یا پارامتر از یک کامپوننت والد به یک کامپوننت فرزند ارسال کنیم تا خروجی فرزند بر اساس داده ورودی تغییر کند.

در واقع props = پارامترهای ورودی یک کامپوننت هستند.


۲. تعریف ساده Props

Props (مخفف Properties) ویژگی‌هایی هستند که هنگام فراخوانی یک کامپوننت به آن داده می‌شوند و داخل آن کامپوننت استفاده می‌شوند.

ویژگی‌های مهم:

  • یک‌طرفه هستند: فقط از والد به فرزند منتقل می‌شوند.
  • Immutable (تغییرناپذیر) هستند: داخل فرزند نباید مقادیر props را تغییر دهیم.
  • هر نوع داده‌ای را می‌توانند حمل کنند: string, number, boolean, array, object, function, حتی JSX.

۳. قیاس برای درک بهتر

تصور کن یک کارخانه داریم که لپ‌تاپ تولید می‌کند.
کامپوننت مثل ماشین تولید لپ‌تاپ است.
Props مثل مواد و مشخصات لپ‌تاپ هستند (CPU, RAM, رنگ و…).
ماشین یکسان است (کامپوننت)، ولی با ورودی متفاوت (props) خروجی متفاوت تولید می‌شود.


۴. نمونه ساده ارسال props

function Welcome(props) {
  return <h1>سلام {props.name}!</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="علی" />
      <Welcome name="سارا" />
    </div>
  );
}

📌 خروجی:

سلام علی!
سلام سارا!

در این مثال:

  • App والد است.
  • Welcome فرزند است.
  • name یک prop است که هر بار مقدارش تغییر می‌کند.

۵. دو روش استفاده از props

روش ۱: دسترسی مستقیم

function UserInfo(props) {
  return <p>نام کاربر: {props.username}</p>;
}

روش ۲: Destructuring (توصیه‌شده)

function UserInfo({ username }) {
  return <p>نام کاربر: {username}</p>;
}

مزایا:

  • کد تمیزتر
  • قابل‌خواندن‌تر
  • راحتی استفاده وقتی props زیاد باشند

۶. ارسال چندین prop همزمان

function Product({ name, price, available }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>قیمت: {price.toLocaleString()} تومان</p>
      <p>{available ? "موجود" : "ناموجود"}</p>
    </div>
  );
}

function App() {
  return (
    <>
      <Product name="کتاب" price={85000} available={true} />
      <Product name="خودکار" price={5000} available={false} />
    </>
  );
}

۷. انواع داده قابل ارسال به عنوان prop

React هیچ محدودیتی روی نوع داده prop ندارد.


1️⃣ رشته و عدد

<User name="فاطمه" age={25} />

📌 رشته‌ها داخل " " یا ' '، اعداد بدون کوتیشن.


2️⃣ متغیر

const city = "تهران";
<Location city={city} />

3️⃣ آرایه

const fruits = ["سیب", "موز", "توت"];
<List items={fruits} />

4️⃣ آبجکت

const person = { name: "علی", age: 24 };
<Profile data={person} />

5️⃣ تابع

function App() {
  const handleClick = () => alert("کلیک شد!");
  return <Button text="ثبت" onClick={handleClick} />;
}

6️⃣ JSX

<Card content={<h2>متن داخل کارت</h2>} />

۸. ویژه: props.children

گاهی لازم است محتوای درون تگ را به فرزند منتقل کنیم:

function Card({ children }) {
  return <div className="card">{children}</div>;
}

function App() {
  return (
    <Card>
      <h3>عنوان کارت</h3>
      <p>توضیحات کارت</p>
    </Card>
  );
}

📌 children تمام محتوای داخل <Card>...</Card> را می‌گیرد.


۹. پشت‌صحنه Props

وقتی می‌نویسیم:

<Welcome name="علی" />

Babel آن را به صورت زیر تبدیل می‌کند:

React.createElement(Welcome, { name: "علی" });

یعنی props یک آبجکت است:

{ name: "علی" }

و مستقیماً به ورودی تابع Welcome پاس داده می‌شود.


۱۰. نکات مهم عملکردی

  • تغییر props باعث رندر مجدد فرزند می‌شود (اگر استفاده شده باشد).
  • props و state مستقل‌اند، ولی props می‌تواند state یک فرزند را مقداردهی اولیه کند.
  • Destructuring در ورودی تابع از نظر عملکرد با props.something تفاوتی ندارد، فقط کد تمیزتر می‌شود.

۱۱. اشتباهات رایج مبتدیان

❌ تغییر مستقیم props:

props.name = "جدید"; // خطا یا رفتار غیرقابل پیش‌بینی

❌ اشتباه گرفتن props با state:

  • props = داده ورودی
  • state = داده داخلی قابل‌تغییر

❌ ارسال رشته بدون کوتیشن:

<Title text=عنوان /> // خطا

❌ استفاده از props بدون ارسال:

function Test({ name }) {
  return <p>{name}</p>;
}
// در والد: <Test /> → name = undefined

۱۲. تمرین‌های عملی

تمرین ۱ — کارت محصول

یک ProductCard بساز که نام، قیمت و توضیحات از props بگیرد.


تمرین ۲ — دکمه پویا

یک Button بساز که متن (label) و اکشن (onClick) را از props بگیرد.


تمرین ۳ — لیست کاربران

یک UserList بساز که آرایه کاربران را از props بگیرد و با map نمایش دهد.


تمرین ۴ — استفاده از children

یک Layout بساز که هدر و فوتر ثابت دارد ولی محتوای وسط از طریق children بیاید.


۱۳. نکات حرفه‌ای در پروژه‌های واقعی

  • همیشه props را type-check کنید (با PropTypes یا TypeScript).
  • از default props استفاده کنید تا در صورت نبود prop، مقدار پیش‌فرض گرفته شود.
  • وقتی props زیاد شدند، حتماً destructuring کنید.
  • برای props پرتکرار، نام‌گذاری واضح و استاندارد داشته باشید.

۱۴. جمع‌بندی

  • props راه ارتباط والد ➡ فرزند است.
  • قابل تغییر نیستند و فقط ورودی هستند.
  • هر نوع داده را پشتیبانی می‌کنند.
  • بسته به نیاز می‌توان با destructuring آن‌ها را باز کرد.
  • props.children امکان ارسال محتوای تو در تو را می‌دهد.
  • رعایت type-check و default props سطح کد را بالا می‌برد.
محمد وب‌سایت

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *