React.Component — کامپوننت‌های کلاسی و نحوه کار آنها

نویسنده: IT Sectr منتشر شده: 2026-07-04 زمان مطالعه: 9 دقیقه

React.Component — کلاس پایه برای ایجاد کامپوننت‌ها با استفاده از وراثت در React. قبل از ظهور هوک‌ها در نسخه 16.8، کامپوننت‌های کلاسی تنها راه مدیریت state و چرخه حیات بودند. طبق React, 2024، کامپوننت‌های کلاسی همچنان پشتیبانی می‌شوند، اگرچه کامپوننت‌های تابعی با هوک‌ها برای پروژه‌های جدید توصیه می‌شوند.

نکات کلیدی

  • React.Component — کلاس پایه‌ای که کامپوننت‌های کلاسی از طریق extends Component از آن ارث می‌برند.
  • State از طریق this.state مدیریت می‌شود و فقط از طریق this.setState به‌روزرسانی می‌شود — تغییر مستقیم ممنوع است.
  • چرخه حیات شامل متدهای componentDidMount، componentDidUpdate و componentWillUnmount است.
  • this در متدهای کلاس نیاز به binding context دارد — از طریق bind، توابع پیکانی یا class fields.
  • مهاجرت به کامپوننت‌های تابعی به تدریج امکان‌پذیر است: هوک‌ها و کلاس‌ها می‌توانند در یک پروژه همزیستی داشته باشند.

React.Component چیست؟

React.Component — یک کلاس انتزاعی است که متدهای داخلی برای کار با state، props و چرخه حیات کامپوننت فراهم می‌کند. برای ایجاد یک کامپوننت کلاسی، باید کلاسی تعریف کنید که از React.Component ارث‌بری کند و متد render را پیاده‌سازی کنید.

React.Component در اولین نسخه React (2013) ظاهر شد و به مدت پنج سال راه اصلی ایجاد کامپوننت‌ها باقی ماند. اکوسیستم React حول کلاس‌ها ساخته شد: کامپوننت‌های مرتبه بالا (HOC)، render props، context — همه این الگوها از طریق سینتکس کلاسی پیاده‌سازی شدند.

با انتشار React 16.8 در سال 2019، تیم React هوک‌ها را به عنوان جایگزینی برای کلاس‌ها معرفی کرد. هوک‌ها همان وظایف — state، اثرات، context — را حل می‌کردند، اما بدون وراثت و binding پیچیده context. React.Component کاملاً پشتیبانی می‌شود، اما برای پروژه‌های جدید رویکرد تابعی توصیه می‌شود.

ایجاد کامپوننت کلاسی

حداقل کامپوننت کلاسی — کلاسی با تنها یک متد render که یک عنصر React برمی‌گرداند. render — تنها متد اجباری است. باید یک تابع خالص از this.props و this.state باشد: همان مجموعه props و state همان نتیجه را می‌دهد.

js
import React, { Component } from 'react';

class Welcome extends Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

سازنده و مقداردهی اولیه state

سازنده قبل از mount اجرا می‌شود. در آن super(props) برای ارسال props به کلاس والد فراخوانی می‌شود و this.state مقداردهی اولیه می‌شود. استفاده از سازنده برای اهداف دیگر — اشتراک‌ها، فراخوانی‌های API — توصیه نمی‌شود: برای این کار componentDidMount وجود دارد.

js
class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  render() {
    return <p>Count: {this.state.count}</p>;
  }
}

مدیریت state از طریق this.state و this.setState

this.state — شیء حاوی داده‌های کامپوننت. تغییر مستقیم آن (this.state.count = 1) ممنوع است — باعث رندر مجدد نمی‌شود و پیش‌بینی‌پذیری را از بین می‌برد. به‌روزرسانی state باید از طریق this.setState انجام شود که یک شیء state جدید ایجاد می‌کند و رندر مجدد را آغاز می‌کند.

setState می‌تواند یک شیء یا تابع دریافت کند. فرم تابعی زمانی ترجیح داده می‌شود که state جدید به state قبلی وابسته باشد: this.setState(prev => ({ count: prev.count + 1 })). React می‌تواند چندین setState را در یک batch برای بهینه‌سازی عملکرد گروه‌بندی کند.

js
class Toggle extends Component {
  constructor(props) {
    super(props);
    this.state = { isOn: false };
  }

  handleClick() {
    this.setState(prev => ({ isOn: !prev.isOn }));
  }

  render() {
    return (
      <button onClick={() => this.handleClick()}>
        {this.state.isOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ویژگی مهم setState — آن ناهمگام است. پس از فراخوانی setState، state بلافاصله به‌روزرسانی نمی‌شود. اگر نیاز به انجام عملی پس از به‌روزرسانی دارید، callback را به عنوان آرگومان دوم ارسال کنید: this.setState(newState, () => console.log(this.state)).

متدهای چرخه حیات

کامپوننت‌های کلاسی متدهای از پیش تعریف شده‌ای دارند که React در لحظات خاصی فراخوانی می‌کند. Mount — constructor → render → componentDidMount. به‌روزرسانی — render → componentDidUpdate. Unmount — componentWillUnmount.

متدفازکاربرد
constructorMountمقداردهی state و binding متدها
renderهر باربازگرداندن عناصر React (اجباری)
componentDidMountپس از mountدرخواست‌های API، اشتراک‌ها، تایمرها
componentDidUpdateپس از به‌روزرسانیواکنش به تغییر props/state
componentWillUnmountقبل از حذفپاکسازی اشتراک‌ها، تایمرها، لغو اشتراک رویدادها

ComponentDidMount — درخواست داده

componentDidMount — مکان اصلی برای اثرات جانبی پس از اولین رندر. در اینجا درخواست‌های HTTP انجام می‌شود، اتصالات WebSocket برقرار می‌شود و تایمرها شروع می‌شوند. اگر اشتراک را در componentWillUnmount پاک نکنید، نشت حافظه رخ می‌دهد.

js
class UserProfile extends Component {
  componentDidMount() {
    fetch(`/api/users/${this.props.userId}`)
      .then(res => res.json())
      .then(data => this.setState({ user: data }));
  }

  componentWillUnmount() {
    // لغو درخواست در unmount
  }

  render() {
    return <div>{this.state.user?.name}</div>;
  }
}

اتصال context this در متدها

در JavaScript، متدهای کلاس به طور پیش‌فرض به نمونه (instance) متصل نیستند. اگر متد را به عنوان callback — به کنترل‌کننده رویداد، تایمر — ارسال کنید، this undefined (در حالت strict) یا window (بدون strict mode) خواهد بود. بدون binding، this.setState خطا می‌دهد.

سه روش برای binding وجود دارد: bind در سازنده، تابع پیکانی در callback، و class field با تابع پیکانی. روش اول — توصیه رسمی React: bind یک بار در سازنده، بدون ایجاد مجدد تابع در هر رندر.

js
// روش 1: bind در سازنده (توصیه شده)
class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({ clicked: true });
  }

  render() {
    return <button onClick={this.handleClick}>Click</button>;
  }
}

Class field — سینتکس مدرن با binding خودکار. تابع پیکانی در ویژگی کلاس، this را از محدوده دید سازنده می‌گیرد. نقطه ضعف — متد روی هر نمونه ایجاد می‌شود، نه روی prototype، که حافظه را برای صدها کامپوننت از یک نوع افزایش می‌دهد.

مقایسه کامپوننت‌های کلاسی و تابعی

انتخاب بین کلاس و تابع — فقط یک مسئله سینتکس نیست. کامپوننت‌های تابعی با هوک‌ها مشکلات ذاتی کلاس‌ها را حل می‌کنند: تکرار منطق در متدهای مختلف چرخه حیات (componentDidMount + componentDidUpdate)، پیچیدگی با this و عدم امکان استخراج منطق مرتبط در یک بلوک قابل استفاده مجدد.

کامپوننت‌های تابعی آسان‌تر برای تست هستند — state داخلی ندارند (که قبل از هوک‌ها فقط در کلاس‌ها بود) و برای بررسی callback‌ها نیاز به mount در DOM ندارند. React کامپوننت‌های تابعی را برای همه پروژه‌های جدید توصیه می‌کند، مستندات و مثال‌ها با آنها نوشته می‌شوند.

کامپوننت‌های کلاسی بهترین انتخاب برای کار با کدهای قدیمی باقی می‌مانند. اگر پروژه قبل از 2019 شروع شده باشد، احتمالاً هزاران کامپوننت کلاسی دارد. بازنویسی همه آنها به هوک در یک اسپرینت ریسک‌ناک است. React سازگاری معکوس را تضمین می‌کند: کامپوننت‌های کلاسی حذف نخواهند شد.

استراتژی مهاجرت از کلاس‌ها به هوک‌ها

مهاجرت تدریجی با تحلیل کامپوننت آغاز می‌شود. کامپوننت‌های ساده بدون state (stateless) اول ترجمه می‌شوند — آنها به سادگی با توابع جایگزین می‌شوند. سپس — کامپوننت‌های با یک یا دو فیلد state، جایی که useState مستقیماً جایگزین this.state و this.setState می‌شود.

کامپوننت‌های پیچیده با متدهای چرخه حیات متعدد از طریق useEffect ترجمه می‌شوند. منطق از componentDidMount + componentDidUpdate به useEffectهای جداگانه با وابستگی‌های مختلف تقسیم می‌شود. componentWillUnmount با تابع بازگشتی داخل useEffect جایگزین می‌شود. برای منطق state پیچیده از useReducer استفاده کنید.

ابزارهای مهاجرت خودکار — @phenomnomnominal/ts-react-class-to-hook یا اسکریپت‌های codemod — می‌توانند کلاس‌های ساده را به طور خودکار تبدیل کنند. برای موارد پیچیده، مهاجرت کار دستی باقی می‌ماند که نیاز به درک منطق کامپوننت اصلی دارد.

سوالات متداول

آیا فراخوانی super(props) در سازنده اجباری است؟

بله. super(props) props را به React.Component والد منتقل می‌کند. بدون این فراخوانی، this.props در داخل سازنده undefined خواهد بود. در render و متدهای چرخه حیات، props حتی بدون super نیز در دسترس هستند، اما این رفتار جانبی پیاده‌سازی است.

چرا setState ناهمگام است؟

React چندین فراخوانی setState را در یک batch برای کاهش تعداد رندرهای مجدد غیرضروری گروه‌بندی می‌کند. اگر setState همگام بود، هر فراخوانی باعث رندر فوری می‌شد و عملکرد را در به‌روزرسانی‌های حجیم کاهش می‌داد.

آیا می‌توان از هوک‌ها در داخل کامپوننت کلاسی استفاده کرد؟

خیر. هوک‌ها فقط در کامپوننت‌های تابعی کار می‌کنند. برای پروژه‌های با کامپوننت‌های کلاسی، تمام الگوهای قدیمی در دسترس هستند: render props، HOC و Consumer برای context. مهاجرت به هوک‌ها نیاز به تبدیل کلاس به تابع دارد.

PureComponent چیست و چه تفاوتی با Component دارد؟

React.PureComponent shouldComponentUpdate را با مقایسه سطحی (shallow) props و state پیاده‌سازی می‌کند. بر خلاف Component که همیشه در setState رندر مجدد می‌کند، PureComponent اگر داده‌ها تغییر نکرده باشند، رندر را رد می‌کند. این یک بهینه‌سازی برای کامپوننت‌های بدون تودرتویی پیچیده است.

چگونه خطا را در کامپوننت کلاسی مدیریت کنیم؟

از componentDidCatch و getDerivedStateFromError استفاده کنید. componentDidCatch(error, info) خطا را ثبت می‌کند. getDerivedStateFromError state را برای نمایش fallback-UI به‌روزرسانی می‌کند. این متدها فقط در کامپوننت‌های کلاسی کار می‌کنند — توابع به یک کامپوننت wrapper ErrorBoundary نیاز دارند.

خلاصه

  • React.Component — کلاس پایه برای کامپوننت‌ها با وراثت، state و متدهای چرخه حیات.
  • this.state در سازنده مقداردهی می‌شود، فقط از طریق this.setState به‌روزرسانی می‌شود — تغییر مستقیم ممنوع است.
  • componentDidMount — مکان اصلی برای درخواست‌های API، اشتراک‌ها و تایمرها پس از اولین رندر.
  • componentWillUnmount — پاکسازی اجباری اشتراک‌ها و تایمرها برای جلوگیری از نشت حافظه.
  • Binding this اجباری است: bind در سازنده — روش توصیه شده برای متدهای callback.
  • هوک‌ها کامپوننت‌های کلاسی را برای پروژه‌های جدید جایگزین کردند، اما کلاس‌ها کاملاً پشتیبانی می‌شوند.
  • مهاجرت به هوک‌ها به تدریج انجام می‌شود: کامپوننت‌های stateless اولویت اول، کامپوننت‌های پیچیده — از طریق useReducer و useEffect.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید