بخش 11: ساخت اولین کامپوننت تابعی در React
1. مقدمه — چرا این بخش مهم است؟
در بخشهای قبلی یاد گرفتیم که کامپوننتها قلب تپنده React هستند.
هر صفحه وب مدرن که با React ساخته شده، ترکیبی از دهها یا حتی صدها کامپوننت کوچک و بزرگ است.
برای مثال:
- یک فروشگاه اینترنتی شامل Header، Footer، ProductCard، ShoppingCart و … است.
- حتی یک دکمه ساده روی صفحه هم در واقع یک کامپوننت جدا میتواند باشد.
اینجا ما روی کامپوننت تابعی (Functional Component) تمرکز میکنیم، چون در React 18 این روش:
- مدرن است
- سادهتر از کلاسهاست
- از هوکها پشتیبانی میکند (نظیر useState و useEffect)
- توسط اکثریت برنامهنویسان React استفاده میشود
📌 تا پایان این بخش، تو میتوانی:
- یک کامپوننت ساده بسازی
- از آن در پروژه استفاده کنی
- به کمک props آن را شخصیسازی کنی
- برایش state اضافه کنی
- خطاهای رایج را تشخیص و برطرف کنی
2. تعریف و توضیح ساده — کامپوننت تابعی چیست؟
کامپوننت تابعی یعنی:
- یک تابع JavaScript
- که نامش با حرف بزرگ شروع میشود
- و JSX برمیگرداند (JSX ترکیبی از HTML و JavaScript است که در بخش 12 یاد میگیریم).
- و میتواند:
- ورودی دریافت کند (props)
- داده داخلی داشته باشد (state)
- رویدادها را مدیریت کند (مثل کلیک، تغییر متن و…)
در سادهترین حالت، یک کامپوننت میتواند فقط یک خط کد باشد:
function Hello() {
return <h1>سلام!</h1>;
}
ولی همین ساختار ساده، قابلیت رشد تا هزاران خط کد را دارد.
3. ساختار کلی یک کامپوننت تابعی
فرمت ساخت یک کامپوننت تابعی:
function ComponentName(props) {
// اینجا میتوانیم state، رویدادها، منطق و ... را داشته باشیم
return (
<div>
{/* اینجا JSX است */}
</div>
);
}
export default ComponentName;
توضیح:
- نام با حرف بزرگ:
ComponentName
→ چون React بر اساس حرف اول متوجه میشود که این یک کامپوننت است، نه یک تگ HTML. - ورودی props: برای گرفتن دادهها از بیرون.
- return: باید دقیقاً یک والد بازگرداند (میتواند
<div>
باشد یا<>
که به آن Fragment گفته میشود). - export default: برای اینکه از این کامپوننت در فایلهای دیگر استفاده کنیم.
4. ساخت گامبهگام اولین کامپوننت تابعی
4.1. ایجاد فایل کامپوننت
بر اساس استاندارد، ما همهی کامپوننتها را داخل پوشه:
src/components/
قرار میدهیم.
پس یک فایل جدید بساز:
src/components/HelloWorld.jsx
4.2. نوشتن کد اولیه
function HelloWorld() {
return <h1>سلام دنیا!</h1>;
}
export default HelloWorld;
4.3. استفاده در App.jsx
در فایل src/App.jsx
:
import HelloWorld from './components/HelloWorld';
function App() {
return (
<div>
<HelloWorld />
</div>
);
}
export default App;
4.4. نتیجه در مرورگر
وقتی پروژه را (npm run dev
) اجرا و باز کنی، نوشته “سلام دنیا!” را میبینی.
5. افزودن استایل به کامپوننت
روش ۱: استایل درونخطی (Inline Style)
function HelloWorld() {
return <h1 style={{ color: "blue", textAlign: "center" }}>سلام دنیا!</h1>;
}
- اینجا یک آبجکت جاوااسکریپت
{}
داخل JSX گذاشتهایم. - ویژگیها باید به صورت camelCase نوشته شوند (مثلاً
backgroundColor
به جایbackground-color
).
روش ۲: فایل CSS جدا
HelloWorld.css
:
.title {
color: green;
text-align: center;
}
و در HelloWorld.jsx
:
import './HelloWorld.css';
function HelloWorld() {
return <h1 className="title">سلام دنیا!</h1>;
}
6. استفاده از Props در کامپوننت تابعی
هدف: ارسال داده از والد (App.jsx
) به فرزند (HelloWorld.jsx
).
HelloWorld.jsx:
function HelloWorld(props) {
return <h1>سلام {props.name}!</h1>;
}
export default HelloWorld;
App.jsx:
<HelloWorld name="علی" />
<HelloWorld name="سارا" />
📌 خروجی:
سلام علی!
سلام سارا!
7. استفاده از Destructuring برای props
به جای props.name
میتوانیم مستقیم از { name }
استفاده کنیم:
function HelloWorld({ name }) {
return <h1>سلام {name}!</h1>;
}
8. افزودن State با useState
در React، برای دادههای داخلی از useState
استفاده میکنیم.
ClickCounter.jsx:
import { useState } from 'react';
function ClickCounter() {
const [count, setCount] = useState(0);
return (
<div>
<p>تعداد کلیک: {count}</p>
<button onClick={() => setCount(count + 1)}>افزایش</button>
</div>
);
}
export default ClickCounter;
📌 هر بار کلیک میکنی، State عوض میشود و کامپوننت دوباره رندر میشود.
9. ترکیب Props و State
فرض کن یک کامپوننت بسازیم که شروعش از یک عدد خاص باشد.
import { useState } from "react";
function Counter({ start }) {
const [count, setCount] = useState(start);
return (
<div>
<p>شمارش: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}
export default Counter;
App.jsx:
<Counter start={5} />
<Counter start={10} />
10. نکات حرفهای در نوشتن کامپوننت
- یک مسئولیت (Single Responsibility) → هر کامپوننت فقط یک کار انجام دهد
- پوشهبندی تمیز → هر کامپوننت یک فایل JSX و در صورت نیاز CSS جداگانه داشته باشد
- قابلیت استفاده مجدد → با props کاری کن که هر بار لازم نباشد دوباره بنویسی
- نامگذاری دقیق →
UserCard
بهتر ازCard
است اگر مخصوص کاربر است
11. اشتباهات رایج مبتدیان
- نوشتن نام با حرف کوچک (
mybutton
) → React آن را HTML فرض میکند - فراموش کردن
export default
یا اشتباه درimport
- برگرداندن چند المنت بدون والد → خطا میدهد: “Adjacent JSX elements must be wrapped…”
- تغییر مستقیم state بدون setState → باعث رندر مجدد نمیشود
12. تمرینهای پیشنهادی
- دکمه سفارشی که متن را از props بگیرد
- کارت محصول با عکس، نام، قیمت (props)
- شمارنده با دو دکمه
+
و-
(state) - لیست کاربران که با map چند کارت را از یک آرایه بسازد
13. جمعبندی
- یک کامپوننت تابعی یک تابع JS است که JSX برمیگرداند.
- props = ورودی از بیرون
- state = داده داخلی
- با ترکیب props و state میتوان UIهای پویا ساخت
- قانون طلایی: هر بخش قابل تکرار UI = یک کامپوننت جداگانه