📚 بخش 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 سطح کد را بالا میبرد.