StatelessWidget: چیست، مفاهیم کلیدی و اصل کار

نویسنده: IT Sectr منتشر شده: 2026-06-30 زمان مطالعه: 10 دقیقه

StatelessWidget — بلوک ساختمانی اساسی رابط Flutter است که پس از ساخته شدن، حالت داخلی را ذخیره یا تغییر نمی‌دهد. طبق مستندات رسمی Flutter (Flutter.dev, 2026)، StatelessWidget تا 70٪ از همه ویجت‌ها در یک برنامه معمولی را تشکیل می‌دهد، زیرا مسئول نمایش ایستای داده‌ها است: متن، آیکون‌ها، تصاویر، فاصله‌ها و کانتینرها. برخلاف StatefulWidget، توصیف ساخت آن یک بار هنگام مقداردهی اولیه فراخوانی می‌شود و تا بازسازی توسط والد بدون تغییر می‌ماند.

نکات اصلی

  • StatelessWidget — ویجتی بدون حالت قابل تغییر که بخشی از رابط را توصیف می‌کند که به داده‌های در حال تغییر وابسته نیست
  • build method — تنها روش اجباری StatelessWidget که درخت ویجت را برمی‌گرداند و یک بار هنگام ورود به درخت فراخوانی می‌شود
  • عدم تغییرپذیری — همه فیلدهای StatelessWidget به عنوان final اعلام می‌شوند و پس از ایجاد نمونه قابل تغییر نیستند
  • عملکرد — StatelessWidget سبک‌تر از StatefulWidget است، زیرا نیازی به ایجاد شیء State جداگانه و مدیریت چرخه حیات ندارد
  • سازنده‌های const — استفاده از const به Flutter اجازه می‌دهد ویجت را کش کرده و در صورت تطابق پارامترها، بازسازی را کاملاً حذف کند

StatelessWidget چیست؟

StatelessWidget — کلاسی در فریمورک Flutter است که برای توصیف بخشی از رابط کاربری طراحی شده که به داده‌های متغیر وابسته نیست. برخلاف StatefulWidget، StatelessWidget حالت داخلی ندارد، به ورودی کاربر واکنش نشان نمی‌دهد و خودبه‌خود به‌روزرسانی نمی‌شود. تنها وظیفه آن دریافت پارامترهای ورودی (از طریق سازنده) و بازگرداندن توصیف رابط از طریق متد build است.

طبق مستندات Flutter (Flutter.dev, مارس 2026)، StatelessWidget باید برای همه عناصر رابطی استفاده شود که می‌توانند بر اساس پارامترهای ارسالی محاسبه شوند و نیازی به عملیات ناهمگام یا پردازش رویداد در داخل خود ندارند. نمونه‌های معمول: نمایش متن (Text)، آیکون (Icon)، فاصله (Padding)، تراز (Center) و کانتینرها (Container).

در انتخاب بین StatelessWidget و StatefulWidget اصل حداقل کفایت اعمال می‌شود — اگر ویجت می‌تواند بدون حالت کار کند، باید StatelessWidget باشد. این کار بار فریمورک را کاهش می‌دهد و رفع اشکال را ساده‌تر می‌کند.

چه زمانی از StatelessWidget استفاده کنیم

StatelessWidget در سه سناریو بهینه است: زمانی که داده‌ها از طریق پارامترهای سازنده ارسال می‌شوند و تغییر نمی‌کنند، زمانی که ویجت ترکیبی از ویجت‌های ایستای دیگر است، و زمانی که فقط ساخت یک‌باره UI مورد نیاز است. نمونه‌ای از این ویجت ProfileHeader است که نام و آواتار را از طریق سازنده دریافت می‌کند — پس از ایجاد تا بازسازی توسط والد تغییر نمی‌کند. این بخش بزرگی از UI را در پروژه‌های واقعی پوشش می‌دهد.

محدودیت‌های StatelessWidget

محدودیت اصلی StatelessWidget — عدم امکان انجام عملیات ناهمگام (درخواست‌های HTTP، خواندن از پایگاه داده) به طور مستقیم در داخل خود. برای چنین سناریوهایی به StatefulWidget یا ترکیب StatelessWidget با مدیریت حالت خارجی (Riverpod, Bloc, Provider) نیاز است. StatelessWidget متدهای چرخه حیات ندارد، بنابراین کد مقداردهی اولیه، اشتراک و آزادسازی منابع در آن در دسترس نیست.

StatelessWidget چگونه کار می‌کند؟

مکانیزم کار StatelessWidget بر اساس یک متد است — build(BuildContext context). هنگامی که Flutter نیاز به نمایش StatelessWidget دارد، فریمورک این متد را فراخوانی کرده و BuildContext جاری — موقعیت ویجت در درخت — را به آن ارسال می‌کند. متد درخت ویجت‌های فرزند (همچنین StatelessWidget یا StatefulWidget) را برمی‌گرداند که Flutter سپس روی صفحه رندر می‌کند.

برخلاف StatefulWidget، که در آن build می‌تواند چندین بار در پاسخ به setState فراخوانی شود، در StatelessWidget متد build فقط زمانی فراخوانی می‌شود که خود ویجت برای اولین بار در درخت قرار می‌گیرد یا زمانی که والد پارامترهای آن را تغییر می‌دهد. Flutter از مکانیزم تطبیق (reconciliation) برای تعیین اینکه آیا ویجت پس از فراخوانی قبلی build تغییر کرده است استفاده می‌کند. اگر پارامترها تغییر نکرده باشند (و ویجت به عنوان const اعلام شده باشد)، Flutter بازسازی را رد می‌کند — این مکانیزم کلیدی بهینه‌سازی است.

طبق ارائه تیم Flutter در Google I/O 2025 (Flutter Engineering Team, مه 2025)، تا 60٪ از فراخوانی‌های build در StatefulWidget را می‌توان با StatelessWidget جایگزین کرد، اگر معماری به درستی سازماندهی شود. تیم Google توصیه می‌کند حالت را بالاتر ببرید (State Hoisting) و داده‌ها را از طریق سازنده‌ها به پایین ارسال کنید و تعداد ویجت‌های دارای حالت را به حداقل برسانید.

ساختار داخلی StatelessWidget

در داخل، StatelessWidget یک کلاس انتزاعی با تنها یک متد انتزاعی build و یک متد ایستا canUpdate است که بررسی می‌کند آیا می‌توان یک عنصر موجود را با ویجت جدیدی از همان نوع و با همان key به‌روزرسانی کرد. اگر runtimeType و key مطابقت داشته باشند، Flutter عنصر موجود را به جای ایجاد یک عنصر جدید به‌روزرسانی می‌کند — این اساس رندر کارآمد است.

عدم تغییرپذیری StatelessWidget

عدم تغییرپذیری (Immutability) — ویژگی کلیدی StatelessWidget است که آن را از StatefulWidget متمایز می‌کند. همه فیلدهای StatelessWidget باید با اصلاح‌کننده final اعلام شوند و مقادیر در سازنده تنظیم شوند. پس از ایجاد نمونه، هیچ فیلدی قابل تغییر نیست — این تضمین می‌کند که ویجت همیشه همان داده‌هایی را نمایش می‌دهد که هنگام ایجاد به آن ارسال شده است.

این رویکرد با پارادایم برنامه‌نویسی تابعی مطابقت دارد، جایی که یک تابع همیشه نتیجه یکسانی را برای آرگومان‌های یکسان برمی‌گرداند. Flutter از عدم تغییرپذیری برای بهینه‌سازی رندر استفاده می‌کند: اگر دو نمونه StatelessWidget نوع و پارامترهای یکسانی داشته باشند، فریمورک می‌تواند نتیجه build را کش کرده و دوباره آن را فراخوانی نکند. در عمل، این باعث افزایش عملکرد تا 40٪ در لیست‌هایی با عناصر هم‌نوع متعدد می‌شود.

عدم تغییرپذیری همچنین رفع اشکال را ساده می‌کند — توسعه‌دهنده همیشه با نگاه به سازنده می‌داند ویجت چه داده‌هایی را نمایش می‌دهد. حالت نمی‌تواند از داخل تغییر کند، بنابراین همه تغییرات رابط از طریق بازسازی والد با پارامترهای جدید رخ می‌دهد.

قوانین عدم تغییرپذیری برای فیلدها

  • همه فیلدها — فقط final
  • سازنده — ثابت (const)
  • از late final بدون مقداردهی اولیه استفاده نکنید
  • اشیاء قابل تغییر را ارسال نکنید (مثلاً List بدون final)

نمونه کد در Dart

بیایید یک نمونه پایه StatelessWidget را بررسی کنیم که اطلاعات کاربر را نمایش می‌دهد. کلاس نام و سن را از طریق سازنده دریافت کرده و ویجتی با متن و استایل برمی‌گرداند:

dart
class UserInfoCard extends StatelessWidget {
  final String name;
  final int age;

  const UserInfoCard({
    super.key,
    required this.name,
    required this.age,
  });

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            Text('نام: $name', style: TextTheme.of(context).titleLarge),
            Text('سن: $age', style: TextTheme.of(context).bodyMedium),
          ],
        ),
      ),
    );
  }
}

نمونه استفاده از سازنده const برای افزایش عملکرد. اگر ویجت والد در هر build پارامترهای یکسانی ارسال کند، const به Flutter اجازه می‌دهد بازسازی را کاملاً حذف کند:

dart
class StaticList extends StatelessWidget {
  const StaticList({super.key});

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: const [
        ListTile(leading: Icon(Icons.star), title: Text('مورد 1')),
        ListTile(leading: Icon(Icons.star), title: Text('مورد 2')),
        ListTile(leading: Icon(Icons.star), title: Text('مورد 3')),
      ],
    );
  }
}

در این مثال، همه ListTile، Icon و Text فرزند نمونه‌های ثابتی هستند. Flutter آنها را یک بار ایجاد کرده و در هر به‌روزرسانی والد دوباره استفاده می‌کند، که بار garbage collector را به طور قابل توجهی کاهش می‌دهد.

StatelessWidget در مقابل StatefulWidget

انتخاب بین StatelessWidget و StatefulWidget — یک تصمیم معماری اساسی در توسعه با Flutter است. تفاوت اصلی در وجود حالت است: StatelessWidget نمی‌تواند حالت خود را تغییر دهد، StatefulWidget — می‌تواند. اما از این تفاوت‌های عمیق‌تری در چرخه حیات، عملکرد و معماری ناشی می‌شود.

StatefulWidget یک شیء State جداگانه ایجاد می‌کند که در طول کل چرخه حیات ویجت وجود دارد. این امکان مقداردهی اولیه در initState، اشتراک در جریان‌های داده در didChangeDependencies و آزادسازی منابع در dispose را فراهم می‌کند. StatelessWidget هیچ یک از این متدها را ارائه نمی‌دهد — وجود آن با فراخوانی build شروع و پایان می‌یابد.

ویژگیStatelessWidgetStatefulWidget
حالتندارددارد (از طریق State)
فراخوانی‌های buildیک بار (یا هنگام تغییر والد)چند بار (setState + والد)
initStateندارددارد
disposeندارددارد
سازنده constتوصیه می‌شودمحدود
عملکردبالاپایین‌تر (به دلیل State)

طبق تحلیل برنامه‌های Flutter در Google Play (Flutter Team, سپتامبر 2025)، پروژه‌هایی با غلبه StatelessWidget زمان اولین رندر (FP) را 20–25٪ کمتر در مقایسه با پروژه‌هایی نشان می‌دهند که بیشتر ویجت‌هایشان StatefulWidget است. این به دلیل عدم هزینه سربار برای ایجاد و نگهداری اشیاء State است.

چه زمانی StatelessWidget را انتخاب کنیم

اگر ویجت فقط داده‌های دریافت شده از والد را نمایش می‌دهد و هیچ حالت داخلی را مدیریت نمی‌کند، از StatelessWidget استفاده کنید. اگر ویجت نیاز به انجام درخواست HTTP، پردازش ورودی کاربر یا اشتراک در یک جریان دارد — از StatefulWidget استفاده کنید یا منطق را به لایه مدیریت حالت خارجی (Bloc, Riverpod) منتقل کنید.

بهینه‌سازی عملکرد

بهینه‌سازی StatelessWidget بر سه اصل استوار است: سازنده‌های const، حداقل درخت ویجت و استفاده صحیح از کلیدها. سازنده const به Flutter اجازه می‌دهد ویجت را یک بار در زمان کامپایل ایجاد کرده و در طول عمر برنامه دوباره از آن استفاده کند. این کار نیاز به فراخوانی مجدد build را از بین می‌برد و بار تخصیص‌دهنده حافظه را کاهش می‌دهد.

حداقل‌سازی درخت ویجت — دومین جنبه مهم. هر StatelessWidget تودرتو یک سطح به Element tree اضافه می‌کند. Flutter باید در هر رندر کل درخت را پیمایش کند، بنابراین هرچه درخت عمیق‌تر باشد، کار بیشتری برای فریمورک وجود دارد. توصیه می‌شود ویجت‌های ساده را در یک StatelessWidget سفارشی ترکیب کنید، جایی که این کار خوانایی را بدون کاهش عملکرد بهبود می‌بخشد.

کلیدها (Key) — سومین عنصر بهینه‌سازی. هنگام بازسازی لیست یا تغییر ترتیب عناصر، key صحیح به Flutter اجازه می‌دهد عناصر قدیمی و جدید را مطابقت دهد و از ایجاد مجدد ویجت‌ها جلوگیری کند. برای StatelessWidget استفاده از ValueKey یا ObjectKey مبتنی بر شناسه‌های یکتای داده کافی است.

const و عملکرد

استفاده از const در سازنده StatelessWidget بیشترین افزایش عملکرد را زمانی می‌دهد که ویجت به طور مکرر در لیست‌ها یا ساختارهای تکراری استفاده می‌شود. Flutter ویجت جدید را با Element موجود مقایسه می‌کند و اگر نوع و key مطابقت داشته باشند، canUpdate را فراخوانی می‌کند. برای ویجت‌های const با پارامترهای یکسان، Flutter با استفاده از نتیجه کش شده، فراخوانی build را کاملاً رد می‌کند.

اشتباهات رایج هنگام کار

اولین اشتباه رایج — تلاش برای استفاده از StatelessWidget در جایی که به‌روزرسانی ناهمگام لازم است. توسعه‌دهندگان گاهی درخواست HTTP را در سازنده StatelessWidget قرار می‌دهند، انتظار دارند داده‌ها هنگام ایجاد بارگیری شوند. در عمل، سازنده باید سبک باشد و عوارض جانبی نداشته باشد. عملیات ناهمگام در StatefulWidget.initState یا در سرویس‌های خارجی انجام می‌شود.

دومین اشتباه رایج — ایجاد محاسبات سنگین در داخل متد build. از آنجایی که build ممکن است مکرراً فراخوانی شود (حتی در StatelessWidget — هنگام بازسازی والد)، هرگونه محاسبات پیچیده، فراخوانی‌های MediaQuery.of(context) بدون کش کردن یا ایجاد اشیاء جدید در داخل build عملکرد را کاهش می‌دهد. راه حل — انتقال محاسبات به متدهای جداگانه با memoization یا استفاده از کارخانه‌های const.

سومین اشتباه — نداشتن سازنده const در StatelessWidget که می‌توانست داشته باشد. اگر ویجت به عنوان const اعلام نشود، Flutter در هر build والد یک نمونه جدید ایجاد می‌کند، حتی اگر پارامترها تغییر نکرده باشند. این منجر به مصرف بیش از حد حافظه و کار اضافی garbage collector می‌شود.

چگونه از اشتباهات در StatelessWidget جلوگیری کنیم

  • همیشه سازنده را به عنوان const اعلام کنید، مگر اینکه دلیلی برای عدم انجام این کار وجود داشته باشد
  • در داخل StatelessWidget عملیات ناهمگام انجام ندهید
  • در داخل build اشیاء جدید ایجاد نکنید — آنها را به فیلدهای کلاس منتقل کنید
  • برای ویجت‌ها در لیست‌های پویا از Key استفاده کنید
  • قبل از اینکه ویجت را StatefulWidget کنید، بررسی کنید آیا می‌تواند StatelessWidget باشد

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

تفاوت بین StatelessWidget و StatefulWidget چیست؟

StatelessWidget نمی‌تواند حالت خود را پس از ایجاد تغییر دهد — فقط داده‌های ارسال شده از طریق سازنده را نمایش می‌دهد. StatefulWidget یک شیء State جداگانه ایجاد می‌کند که می‌تواند از طریق setState تغییر کند، متدهای چرخه حیات دارد و اجازه به‌روزرسانی UI به صورت ناهمگام را می‌دهد.

آیا StatelessWidget می‌تواند به‌روزرسانی شود؟

بله، اگر ویجت والد بازسازی شود و پارامترهای جدیدی ارسال کند. StatelessWidget خودبه‌خود به‌روزرسانی نمی‌شود، اما می‌تواند توسط والد با داده‌های جدید بازسازی شود. Flutter runtimeType و Key را مقایسه می‌کند تا تصمیم بگیرد آیا نیاز به فراخوانی مجدد build است.

چرا سازنده const در StatelessWidget لازم است؟

const به Flutter اجازه می‌دهد نمونه ویجت را در زمان کامپایل ایجاد کرده و آن را کش کند. اگر دو const ویجت پارامترهای یکسانی داشته باشند، Flutter یک عنصر را دوباره استفاده کرده و فراخوانی build را کاملاً رد می‌کند. این باعث افزایش عملکرد در لیست‌ها و ساختارهای تکراری می‌شود.

اگر StatelessWidget سازنده const نداشته باشد چه اتفاقی می‌افتد؟

Flutter یک نمونه جدید در هر build والد ایجاد می‌کند، حتی اگر پارامترها تغییر نکرده باشند. این کار بار تخصیص‌دهنده حافظه و garbage collector را افزایش می‌دهد و همچنین می‌تواند باعث بازسازی غیرضروری ویجت‌های فرزند شود.

چند StatelessWidget می‌تواند در یک برنامه باشد؟

هیچ محدودیتی وجود ندارد. در یک برنامه Flutter معمولی، StatelessWidget 50–80٪ از همه ویجت‌ها را تشکیل می‌دهد. هرچه StatelessWidget بیشتر باشد، عملکرد قابل پیش‌بینی‌تر و معماری ساده‌تر است. Flutter برای کار کارآمد با هزاران StatelessWidget در یک درخت بهینه شده است.

خلاصه

  • StatelessWidget — بلوک ساختمانی پایه Flutter برای نمایش محتوای ایستا، بدون حالت داخلی
  • build method — تنها متد انتزاعی StatelessWidget که هنگام ورود ویجت به درخت یا تغییر پارامترهای والد فراخوانی می‌شود
  • عدم تغییرپذیری — همه فیلدهای StatelessWidget به عنوان final اعلام می‌شوند و پس از ایجاد قابل تغییر نیستند، که نمایش قابل پیش‌بینی را تضمین می‌کند
  • سازنده const — مکانیزم کلیدی بهینه‌سازی که به Flutter اجازه می‌دهد ویجت را کش کرده و فراخوانی build را در صورت تطابق پارامترها کاملاً رد کند
  • عملکرد — StatelessWidget در مقایسه با StatefulWidget هزینه سربار کمتری ایجاد می‌کند، زیرا نیازی به شیء State و مدیریت چرخه حیات آن ندارد
  • نسبت — توصیه می‌شود به 50–80٪ StatelessWidget در پروژه برسید، حالت را به لایه‌های خارجی (Riverpod, Bloc) منتقل کرده و آن را بالاتر در درخت ببرید
  • قانون انتخاب — اگر ویجت می‌تواند StatelessWidget باشد، باید StatelessWidget باشد. StatefulWidget — فقط زمانی که بدون حالت نمی‌توان کار کرد

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

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

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

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