لماذا نستخدم كلمة widget

titleController.text = widget.post.title; لماذا نستخدم كلمة widget هنا

هذه من أكثر النقاط التي تسبب حيرة للمبتدئين في Flutter.

لننظر أولاً إلى الكود:

class EditPostPage extends StatefulWidget {

  final PostModel post;

  const EditPostPage({
    super.key,
    required this.post,
  });

  @override
  State<EditPostPage> createState() =>
      _EditPostPageState();
}
Dart

هنا المتغير:

post
Dart

موجود داخل:

EditPostPage
Dart

وليس داخل:

_EditPostPageState
Dart

ماذا يحدث عند فتح الصفحة؟

عندما نكتب:

EditPostPage(
  post: post,
)
Dart

يتم إنشاء Widget جديدة.

هذه الـ Widget تحتوي:

final PostModel post;
Dart

ثم ماذا؟

Flutter تنشئ State خاص بها:

_EditPostPageState
Dart

أصبح لدينا كائنان مختلفان:

الكائن الأول

EditPostPage
Dart

ويحتوي:

post
Dart

الكائن الثاني

_EditPostPageState
Dart

ويحتوي:

titleController
bodyController
isLoading
Dart

المشكلة

داخل State نحاول الوصول إلى:

post
Dart

لكن:

post
Dart

غير موجودة داخل State.


هذا خطأ:

titleController.text =
    post.title;
Dart

لأن State لا تملك متغيراً اسمه post.


كيف أصل للـ Widget من داخل State؟

Flutter توفر متغيراً جاهزاً اسمه:

widget
Dart

هذا المتغير يشير إلى:

EditPostPage
Dart

الحالية.


لذلك:

widget.post
Dart

تعني:

أعطني post الموجودة داخل EditPostPage
Dart

صورة ذهنية

تخيل:

EditPostPage

├── post

└── _EditPostPageState

    ├── titleController
    ├── bodyController
    └── isLoading
Dart

عندما يكون State بحاجة للوصول إلى:

post
Dart

فهو يصعد إلى Widget:

widget.post
Dart

مثال أبسط

class UserPage extends StatefulWidget {

  final String name;

  const UserPage({
    required this.name,
  });

  @override
  State<UserPage> createState() =>
      _UserPageState();
}
Dart

داخل State:

class _UserPageState
    extends State<UserPage> {

  @override
  void initState() {

    super.initState();

    print(widget.name);
  }
}
Dart

هنا:

widget.name
Dart

تعني:

UserPage.name
Dart

لماذا لا نكتب this.post ؟

لأن:

this
Dart

تشير إلى:

_EditPostPageState
Dart

وليس إلى:

EditPostPage
Dart

مثال:

print(this.runtimeType);
Dart

سيطبع:

_EditPostPageState
Dart

أما:

widget.runtimeType
Dart

سيطبع:

EditPostPage
Dart

قاعدة ذهبية

داخل:

StatefulWidget
Dart

أي متغير مرسل عبر Constructor مثل:

final PostModel post;
Dart

يتم الوصول إليه داخل State بواسطة:

widget.post
Dart

وليس:

post
Dart

وليس:

this.post
Dart

لذلك هذا السطر:

titleController.text =
    widget.post.title;
Dart

معناه حرفياً:

خذ عنوان المنشور الموجود داخل EditPostPage
وضعه داخل TextField عند فتح الصفحة.
Dart