مدیریت State و روش های آن در فلاتر

روش های مدیریت State در فریمورک هایی چون Flutter و React Native همیشه یکی از داغ ترین بحث هاست و افراد نظرات و شیوه های مختلفی برای انجام این کار دارند.

در این مطلب هدف ما بررسی روش های مدیریت State در فریمورک فلاتر هست.

کتابخانه و راه های مختلفی برای انجام این کار وجود داره و بعضی وقت ها افراد فرض میکنند که هرچقدر راه طولانی تر و سخت تری را طی کنند بهتر میتونند مدیریت State و پیاده سازی کنند اما فقط باعث افزایش پیچیدگی پروژه می شود. اما گاهی اوقات هم نتایج بسیار خوبی دربر خواهد داشت.

پس توصیه میکنم که همیشه متکی به یک راه و روش یا کتابخانه نباشید و پروژه و نیازمندی های خودتون و بررسی کنید و سپس بهترین گزینه و انتخاب کنید.

تعریف State

اول از همه شاید بهتر باشه برای افرادی که هنوز مدت زمان زیادی نیست که با برنامه نویسی آشنا شده اند توضیح بدیم که State به شکل ساده چی هست.

به اطلاعاتی که در طول چرخه حیات یک اپلیکیشن تغییر میکنند State میگیم.

رابط کاربری برنامه شما در واقع نمایشی از این State ها می باشد و وقتی مقدار یک State را تغییر می دهد ویجت ها و رابط کاربری اپلیکیشن دوباره از نو ساخته می شود.

چرا نیاز به مدیریت State داریم

همزمان با اینکه پروژه شما رفته رفته بزرگ تر و پیچیده تر میشه شما با باگ هایی برخورد میکنید که مستقیما به دلیل جریان ورود اطلاعات توسط کاربر یا منابع دیگه می باشد.

مدیریت صحیح روش های بروزرسانی State باعث میشه که کمتر با خطاهایی در زمان اجرای برنامه مواجه شوید و کارایی اپلیکیشن بهبود پیدا می کند.

فلاتر بصورت پیش فرض یک سری پکیج داخل خودش داره که برای مدیریت State میتونیم ازشون استفاده کنیم که شامل موارد زیر هست:

  • StatefulWidget
  • StatefulBuilder
  • StreamBuilder
  • InheritedWidget

علاوه بر این ابزارهای مختلف دیگه مثل RxDart و Bloc هم به عنوان موارد خارجی کاربرهای زیادی برای ما دارند.

اگر در یک صفحه از اپلیکیشن خودتون نیاز به تغییرات اطلاعات ندارید و صرفا حالت نمایشی دارند محتویات, میتونید تمام State ها را داخل یک ویجت قرار دهید.

اما به تصویر زیر نگاه کنید, اگر نیاز دارید تا اطلاعاتی و از ویجت های فرزند به ریشه درخت ارسال کنید در این صورت نیاز به یکی از روش های مدیریت State دارید.

ویجت StatefulWidget

در این ویجت با استفاده از دستور SetState میتونید مقادیر خودتون و هروقت که نیاز بود تغییر بدید.

در واقع اولین و ساده ترین راه برای مدیریت state همین روش می باشد.

ویجت StatefulWidget نیاز به دو کلاس مختلف و مقداری کدنویسی اضافه داره که باعث گرفته شدن وقت میشه و راه های آسان تری هم برای پیاده سازی این روش وجود داره که باهم دیگه بررسی میکنیم.


استفاده از StatefulBuilder میتونه جایگزین بهتری باشه در برخی مواقع.

ویجت InheritedWidget

این ویجت به تمام ویجت های فرزند خودش یک context اختصاص میده و با استفاده از آن میتونید تغییراتی که نیاز دارید و اعمال کنید.

این روش هم نیاز به کدنویسی زیادی نسبت به بقیه روش ها داره که باعث میشه افراد زیادی استفاده نکنند.

و از روش های دیگه مثل Bloc, Redux, ,Scoped Model استفاده کنند.

ترکیب StreamBuilder + RxDart BehaviorSubject

این روش یکی از بهترین راه ها برای مدیریت State های global می باشد که انعطاف پذیری بالایی دارد و به خوبی نیازهای شما را رفع می کند.

BehaviorSubject ویژگی و قابلیت های متنوعی دارد که باعث میشود به ابزاری مناسب برای مدیریت State تبدیل شود.

  • دارای یک مقدار ارزش فعلی ( current value) هست که به صورت همروند قابل دسترس است.
  • قابلیت تبدیل به عملگرهای RxDart را دارد.
  • دارای یک جریان (stream) بصورت اشتراکی و broadcast می باشد.

در زیر باهم دیگه به بررسی یک مثال میپردازیم که قصد داریم از عدد صفر شروع به شماردن کنیم.

در واقع مقدار current value را میخونیم و سپس یک عدد به آن اضافه میکنیم.

کلاس Counter بخش منطقی برنامه و ایجاد میکند و همچنین یک state که از همه جا به آن دسترسی داریم.

در واقع در این روش از الگوی Observable استفاده میکنیم و stream$ را به StreamBuilder  پاس میدیم تا هروقت مقداری جدیدی داخل آن قرار گرفت ویجت ما هم آپدیت بشه.

تنها مشکلی که روش بالا دارد این هست که از یک متغیر سراسری برای اشتراک گذاری state استفاده می کند.

الگوی BLoC

روش BLoC تقریبا شبیه به InheritedWidget می باشد اما مرتب تر و قابل بسط دادن می باشد.

برای این که بتونید راحت تر این نوع الگو را پیاده سازی کنید میتونید از پکیج flutter_bloc استفاده کنید.

روش پیاده سازی تقریبا شبیه به Redux می باشد که شامل موارد زیر هست.

  • تعریف رویداد Events/Actions
  • ایجاد یک کلاس (bloc) که mapEventToState را پیاده سازی می کند و هر زمان که رویدادی رخ داد مقدار State را محاسبه می کند.
  • قرار دادن BlocProvider در ریشه درخت ویجت ها تا تمام فرزندان بتوانند به مقدار آن دسترسی داشته باشند.
  • استفاده از BlockBuilder برای بازسازی ویجت زمانی که State تغییر می کند.
  • استفاده از dispatch برای بررسی رویدادهایی که مقدار state را تغییر می دهند.

ابزارهای جانبی

به غیر از موارد بالا که بررسی کردیم ابزارها و کتابخانه های مختلف دیگری برای مدیریت State در فلاتر وجود دارند که مهم ترین آنها شامل موارد زیر هست.

منبع: مرجع فارسی فلاتر