في المقال السابق، تحدثنا عن مفهوم إدارة الحالة في Flutter وكيف يمكن أن يصنع الفرق بين تطبيق منظم وتطبيق مليء بالفوضى.
نبدأ أول خطوة عملية نحو الاحتراف — مع النمط الأشهر والأبسط في هذا المجال: Provider في Flutter .
ما هو Provider بالضبط؟
تخيل أن تطبيقك أشبه بمدينة كبيرة .
كل شاشة فيها تمثل “منطقة”، وكل ويدجت يمثل “منزلًا”.
الآن، إذا أردت أن تُرسل معلومة من أحد المنازل إلى منطقة أخرى، فهل ستسير بها يدويًا من شارع إلى شارع؟
بالطبع لا. تحتاج إلى شبكة اتصال مركزية — وهنا يأتي دور Provider في Flutter .
ببساطة، Provider هو نظام توزيع بيانات بين ويدجتات التطبيق بطريقة منظمة وآمنة.
يسمح لك بمشاركة الحالة (State) بين أجزاء متعددة دون الحاجة إلى تمرير المتغيرات يدويًا عبر كل ويدجت.
الفكرة الأساسية وراء Provider
في Flutter، كل شيء هو ويدجت (Widget).
لكن عندما يتغير شيء ما في البيانات، تحتاج الواجهة إلى إعادة البناء لتحديث العرض.
الـ Provider يقوم بربط البيانات بالواجهة بحيث يُعاد بناء الأجزاء المتأثرة فقط، مما يجعل التطبيق أسرع وأكثر كفاءة.
فبدلاً من استخدام setState() في كل مكان، نضع الحالة داخل كائن خاص (Model أو ChangeNotifier)، ثم نستخدم Provider ليُبلغ الواجهة عندما تتغير البيانات.
مثال عملي: عدّاد باستخدام Provider
لنبدأ بمثال بسيط جدًا لتوضيح الفكرة 👇
الخطوة 1: إعداد الـ Model
import 'package:flutter/foundation.dart';
class CounterModel with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // يخبر الواجهة أن هناك تغييراً حدث
}
}
🧩 الخطوة 2: إضافة Provider إلى التطبيق
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'counter_model.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => CounterModel(),
child: MyApp(),
),
);
}
🧩 الخطوة 3: استخدام البيانات في الواجهة
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counter = Provider.of<CounterModel>(context);
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Provider Counter')),
body: Center(
child: Text(
'${counter.count}',
style: TextStyle(fontSize: 40),
),
),
floatingActionButton: FloatingActionButton(
onPressed: counter.increment,
child: Icon(Icons.add),
),
),
);
}
}
🎉 تهانينا!
لقد قمت للتو بإنشاء أول تطبيق يستخدم Provider لإدارة الحالة بدلًا من setState().
كيف يعمل هذا السحر؟
- ChangeNotifier هو الكائن الذي يخبر الواجهة أن شيئًا ما تغير.
- Provider يربط هذا الكائن بباقي أجزاء التطبيق.
- Consumer أو Provider.of() تسمح بقراءة الحالة وإعادة بناء الواجهة تلقائيًا عند التغيير.
وهكذا، عندما تنفذ notifyListeners()، يتم تحديث الواجهة فورًا — فقط في الأماكن التي تعتمد على تلك البيانات.
⚠️ الأخطاء الشائعة
- استخدام Provider.of(context) داخل
build()مباشرة بدون الاستماع الصحيح → يؤدي إلى إعادة بناء زائدة.
💡 الحل: استخدمConsumerأوSelectorللتحكم في إعادة البناء. - نسيان notifyListeners() بعد تعديل البيانات → التغييرات لن تظهر على الواجهة.
- وضع Provider في مكان غير مناسب داخل شجرة الودجات → البيانات لن تكون متاحة في جميع الأجزاء المطلوبة.
نصائح من مطورين محترفين
- استخدم MultiProvider عند وجود أكثر من حالة في التطبيق.
- حاول دائمًا الفصل بين واجهة المستخدم والمنطق (Business Logic).
- استخدم Selector لتحسين الأداء في الواجهات الكبيرة.
لماذا Provider هو محطة مهمة؟
لأنه ببساطة يعلّمك التفكير المنطقي في تنظيم البيانات.
هو الجسر الذي ينتقل بك من الفوضى العشوائية مع setState() إلى مفهوم “الحالة المركزية” الذي تعتمد عليه الأنماط المتقدمة مثل Riverpod وBloc.
المقال القادم
في المقال القادم ، سنتعرف على Riverpod — التطور الطبيعي لـ Provider.
ستكتشف كيف يجعلك تتحكم في الحالة بشكل أكثر مرونة، وبدون الحاجة إلى ChangeNotifier أو Boilerplate code.

