کلاس ها (Class)
اینجا قرار است با کامپوننت کلاسی ری اکت آشنا شوی. این نوع کامپوننت ها قبل از هوک ها، تنها راه داشتن state و چرخه حیات بودند. الان بیشتر وقت ها از کامپوننت تابعی استفاده می کنیم، اما هنوز دانستن کلاس ها مفید است، مخصوصا وقتی با کدهای قدیمی کار می کنی.
کامپوننت کلاسی ری اکت چیست؟
کامپوننت کلاسی ری اکت یک کلاس جاوااسکریپت است که از React.Component ارث بری می کند. این کلاس یک متد مهم به نام render() دارد که دقیقا مشخص می کند چه JSX باید روی صفحه نمایش داده شود.
قبل از نسخه 16.8 ری اکت، فقط با همین کامپوننت های کلاسی می شد state و lifecycle (چرخه حیات) را کنترل کرد. بعد از اضافه شدن هوک ها، تقریبا همه کارها را می شود داخل کامپوننت های تابعی انجام داد، اما کلاس ها هنوز حذف نشده اند.
برای مقایسه کلی ساختار کامپوننت ها، می توانی صفحه کامپوننت کلاسی ری اکت را هم ببینی.
ساخت اولین کلاس در ری اکت
اسم کامپوننت باید با حرف بزرگ شروع شود؛ مثلا Car. همچنین کلاس باید از React.Component ارث بری کند تا به امکانات ری اکت دسترسی داشته باشد.
مثال: کلاس ساده Car
class Car extends React.Component {
render() {
return (
<h2>Hi, I am a Car!</h2>
);
}
}
این کلاس یک کامپوننت کلاسی ری اکت است. متد render() هر بار صدا زده می شود و JSX را برمی گرداند. این JSX در نهایت به HTML واقعی تبدیل می شود.
رندر کردن کلاس روی DOM
برای نمایش این کلاس روی صفحه، باید آن را مثل یک تگ سفارشی استفاده کنی و با createRoot(...).render(...) رندر کنی.
createRoot(document.getElementById("root")).render(
<Car />
);
اول المنت با شناسه root پیدا می شود. سپس متد render کامپوننت <Car /> را داخل آن نمایش می دهد؛ مثل این که به ری اکت بگویی «این جا محل نمایش، این هم کامپوننت.»
constructor و state در کلاس ها
سازنده یا constructor متدی است که هنگام ساخته شدن شیء کلاس اجرا می شود. در کامپوننت کلاسی ری اکت، این جا جایی است که state اولیه را تنظیم می کنی. state یک شیء است که داده های متغیر کامپوننت را نگه می دارد.
در سازنده باید اول super() را صدا بزنی تا والد یعنی React.Component درست مقداردهی شود. بعد می توانی روی this.state مقدار بگذاری.
مثال: تعریف state در سازنده
class Car extends React.Component {
constructor() {
super();
this.state = {
color: "red"
};
}
render() {
return (
<h2>I am a Car!</h2>
);
}
}
اینجا state یک ویژگی به نام color دارد. فعلا از آن در render استفاده نکرده ایم، اما بعد می توانیم رنگ را در متن نشان دهیم.
استفاده از state داخل render
class Car extends React.Component {
constructor() {
super();
this.state = {
color: "red"
};
}
render() {
return (
<h2>I am a {this.state.color} Car!</h2>
);
}
}
اینجا از this.state.color داخل JSX استفاده شده است. هر وقت state عوض شود، خروجی این متن هم تغییر می کند.
props در کامپوننت کلاسی ری اکت
پراپس (Props) شبیه ورودی های تابع هستند. وقتی کامپوننت را مثل تگ HTML صدا می زنی، می توانی ویژگی هایی مثل color="red" به آن بدهی. داخل کلاس، این مقدارها از طریق this.props در دسترس هستند.
مثال: گرفتن رنگ از props
class Car extends React.Component {
render() {
return (
<h2>I am a {this.props.color} Car!</h2>
);
}
}
createRoot(document.getElementById("root")).render(
<Car color="red" />
);
در این مثال، مقدار color از بیرون فرستاده می شود و کلاس فقط از this.props.color استفاده می کند. این یعنی یک کلاس را می توان چند بار با داده های مختلف استفاده کرد.
برای توضیح کامل تر پراپس، می توانی بعدا بخش پراپس در ری اکت را هم بخوانی.
state و setState در کلاس ها
state جایی است که اطلاعات متغیر کامپوننت نگه داشته می شود؛ مثل رنگ، مدل یا سال ساخت ماشین. برای تغییر state هرگز مستقیم به this.state مقدار جدید نمی دهیم. همیشه باید از this.setState() استفاده کنیم تا ری اکت بفهمد باید دوباره رندر کند.
مثال: تغییر رنگ با دکمه
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {
brand: "Ford",
model: "Mustang",
color: "red",
year: 1964
};
}
changeColor = () => {
this.setState({
color: "blue"
});
};
render() {
return (
<div>
<h1>My {this.state.brand}</h1>
<p>
It is a {this.state.color}
{this.state.model}
from {this.state.year}.
</p>
<button
type="button"
onClick={this.changeColor}
>
Change color
</button>
</div>
);
}
}
createRoot(document.getElementById("root")).render(
<Car />
);
با کلیک روی دکمه، متد changeColor صدا زده می شود و با setState رنگ از قرمز به آبی تغییر می کند. ری اکت تغییر را می بیند و دوباره کامپوننت را رندر می کند.
نکته: همیشه برای تغییر state از setState استفاده کن. تغییر مستقیم this.state ممکن است باعث شود ری اکت آپدیت را متوجه نشود.
چرخه حیات کامپوننت کلاسی ری اکت
چرخه حیات (Lifecycle) یعنی کامپوننت از لحظه ساخته شدن تا از بین رفتن، چه مراحلی را طی می کند. سه فاز اصلی داریم: Mounting (اضافه شدن به DOM)، Updating (به روزرسانی) و Unmounting (حذف از DOM).
در فاز Mounting، متدهایی مثل constructor، getDerivedStateFromProps، render و componentDidMount به ترتیب اجرا می شوند. برای ما، constructor و componentDidMount خیلی ملموس هستند.
مثال: تغییر رنگ بعد از Mount شدن
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {
favoritecolor: "red"
};
}
componentDidMount() {
setTimeout(() => {
this.setState({
favoritecolor: "yellow"
});
}, 1000);
}
render() {
return (
<h1>
My Favorite Color is {this.state.favoritecolor}
</h1>
);
}
}
createRoot(document.getElementById("root")).render(
<Header />
);
ابتدا رنگ موردعلاقه قرمز است. بعد از یک ثانیه، در componentDidMount رنگ به زرد عوض می شود. این مثال نشان می دهد که می توانی بعد از قرار گرفتن کامپوننت در DOM، کارهایی مثل درخواست شبکه یا تایمر انجام دهی.
در فاز Updating هم متدهایی مثل shouldComponentUpdate، render، getSnapshotBeforeUpdate و componentDidUpdate وجود دارند که رفتار آپدیت شدن را کنترل می کنند. برای شروع، همین که بدانی با تغییر state یا props کامپوننت دوباره رندر می شود، کافی است.
گام های تمرینی با کلاس ها
برای این که مفاهیم کامپوننت کلاسی ری اکت خوب در ذهنت بنشیند، این مراحل را انجام بده.
- یک کلاس
Studentبساز که ازReact.Componentارث بری کند و درrenderیک پیام سلام ساده نمایش دهد. - برای
Studentیک سازنده تعریف کن، state اولیه با یک نام بگذار و آن نام را در خروجی نشان بده. - یک دکمه اضافه کن که با
setStateنام را تغییر دهد؛ مثل عوض شدن لقب تو در بازی.
اگر خواستی بعدا بیشتر روی تفکیک بین کامپوننت تابعی و کلاسی کار کنی، صفحه کامپوننت ها (Components) جای خوبی برای مرور است.
جمع بندی سریع
- کامپوننت کلاسی ری اکت یک کلاس است که از
React.Componentارث بری می کند. - متد
render()همیشه باید وجود داشته باشد و JSX برگرداند. - state در سازنده روی
this.stateتنظیم می شود. - برای تغییر state همیشه از
this.setState()استفاده کن. - متدهایی مثل
componentDidMountبخشی از چرخه حیات کامپوننت کلاسی هستند.