شارك المقالة
تعرف على مزايا HydratedBloc في Flutter لإدارة الحالة، وكيف يحافظ على البيانات بين جلسات التطبيق ويجعل تجربة المستخدم أفضل من الطرق التقليدية.

HydratedBloc في Flutter: شرح حفظ الحالة وإدارة State باحتراف

  إدارة الحالة (State Management) من أهم التحديات في تطوير تطبيقات Flutter، خصوصًا عند الحاجة إلى الاحتفاظ ببيانات التطبيق بعد إغلاقه. هنا يأتي دور HydratedBloc كحل عملي وفعال يتيح حفظ الحالة تلقائيًا واستعادتها عند إعادة تشغيل التطبيق، مما يوفر تجربة مستخدم أكثر سلاسة واستقرارًا.  

لماذا نستخدم HydratedBloc لحفظ الحالة في Flutter؟

في التطبيقات الحقيقية، يحتاج المستخدم إلى استكمال ما بدأه دون فقدان البيانات. بدلًا من إعادة تحميل الحالة أو استخدام حلول يدوية مثل SharedPreferences، يوفر HydratedBloc آلية ذكية لحفظ الحالة واسترجاعها تلقائيًا دون تعقيد.  

ما هو HydratedBloc؟

HydratedBloc هو امتداد لمكتبة Bloc يضيف ميزة التخزين المحلي التلقائي للحالة. يعتمد على مكتبة hydrated_bloc التي تقوم بتخزين الحالة بصيغة JSON في التخزين المحلي باستخدام Hive أو SharedPreferences. عند إعادة تشغيل التطبيق، يتم استعادة آخر حالة محفوظة تلقائيًا دون أي تدخل من المطور. عندما يتم إغلاق التطبيق أو إعادة تشغيله، يتم حفظ الحالة الحالية في التخزين المحلي، ويمكن استعادتها عند تشغيل التطبيق مرة أخرى. هذا يجعل HydratedCubit أداة مثالية للتطبيقات التي تحتاج إلى الحفاظ على بيانات المستخدم أو حالة التطبيق بين الجلسات.

كيفية تثبيت hydrated_bloc في مشروع Flutter

أضف الاعتمادات التالية إلى ملف pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  hydrated_bloc: ^8.0.0
  path_provider: ^2.0.11
 

تهيئة HydratedBloc عند تشغيل التطبيق

قبل استخدام HydratedCubit أو HydratedBloc، يجب تهيئة التخزين في نقطة بدء التطبيق:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  HydratedBloc.storage = await HydratedStorage.build(
    storageDirectory: await getTemporaryDirectory(),
  );

  runApp(const MyApp());
}

استخدام HydratedCubit مع Cubit


class CounterCubit extends HydratedCubit {
  CounterCubit() : super(const CounterInit());

  void increment() {
    emit(CounterUpdate(state.count + 1));
  }

  void decrement() {
    emit(CounterUpdate(state.count - 1));
  }

  @override
  CounterState? fromJson(Map<String, dynamic> json) {
    return CounterUpdate(json['count']);
  }

  @override
  Map<String, dynamic>? toJson(CounterState state) {
    return {'count': state.count};
  }
}
  في هذا المثال:
  • يتم حفظ قيمة العداد تلقائيًا
  • fromJson تُستخدم لاستعادة الحالة
  • toJson تُستخدم لحفظ الحالة في التخزين المحلي
 

استخدام HydratedBloc مع Bloc


class TaskBloc extends HydratedBloc<TaskEvent, TaskState> {
  TaskBloc() : super(TaskInitial()) {
    on(_addTask);
    on(_removeTask);
    on(_toggleTask);
  }

  void _addTask(AddTaskEvent event, Emitter emit) {
    final task = TaskModel(
      id: const Uuid().v4(),
      title: event.title,
      isCompleted: false,
    );
    emit(UpdateTask([...state.tasksList, task]));
  }

  void _removeTask(RemoveTaskEvent event, Emitter emit) {
    emit(UpdateTask(
      state.tasksList.where((t) => t.id != event.id).toList(),
    ));
  }

  void _toggleTask(ToggleTaskEvent event, Emitter emit) {
    emit(UpdateTask(
      state.tasksList.map((task) {
        return task.id == event.id
            ? task.copyWith(isCompleted: !task.isCompleted)
            : task;
      }).toList(),
    ));
  }

  @override
  TaskState? fromJson(Map<String, dynamic> json) {
    return UpdateTask(
      (json['tasks'] as List)
          .map((e) => TaskModel.fromJson(e))
          .toList(),
    );
  }

  @override
  Map<String, dynamic>? toJson(TaskState state) {
    return {
      'tasks': state.tasksList.map((e) => e.toJson()).toList(),
    };
  }
}
 

تعريف حالة المهام (State)


abstract class TaskState {
  final List tasksList;
  TaskState(this.tasksList);
}

class TaskInitial extends TaskState {
  TaskInitial() : super([]);
}

class UpdateTask extends TaskState {
  UpdateTask(List tasksList) : super(tasksList);
}
 

متى لا يكون HydratedBloc هو الخيار المناسب؟

 
  • عند التعامل مع بيانات حساسة (مثل كلمات المرور)
  • عند الحاجة إلى تخزين مؤقت فقط
  • في الحالات التي تتطلب مزامنة فورية مع السيرفر
 

مزايا استخدام HydratedBloc في Flutter

  • حفظ واستعادة الحالة تلقائيًا
  • تقليل الكود المتكرر
  • تحسين تجربة المستخدم
  • تكامل مثالي مع Bloc

أسئلة شائعة حول HydratedBloc

هل HydratedBloc يؤثر على أداء التطبيق؟

لا، يتم التخزين بطريقة غير متزامنة ولا يؤثر بشكل ملحوظ على الأداء.

هل يمكن استخدام HydratedBloc مع Riverpod؟

لا، HydratedBloc مصمم خصيصًا للعمل مع Bloc و Cubit.
شاهد أيضًا
مقالات ذات صلة
شرح كيفية التعامل مع رفع الصور داخل nodejs باستخدام multer

تعرف على مكتبة Multer: الحل الأمثل لتحميل الملفات في Node.jsكيفية التعامل مع رفع الصور داخل…

بناء تطبيق Flutter للتعرف على النصوص (OCR) باستخدام الكاميرا

في هذا المقال، سنقوم ببناء تطبيق Flutter OCR بسيط لاستخراج الكلمات من النصوص المصوّرة. يعتمد…

اكتب برنامج بلغة الجافا يقوم بحساب الاعمار || Write a program in Java that calculates ages

  هذا الكود المكتوب بلغة الجافا يقوم بعملية حساب الاعمار وكل ما عليك ان تفعله…

🚫 مانع الإعلانات مفعل

يجب إيقاف مانع الإعلانات لاستكمال تصفح الموقع