- بواسطة x32x01 ||
لو ظهر لك في Flutter تحذير عن استخدام
المشكلة إن الكود ممكن ينتظر عملية غير متزامنة، وخلال فترة الانتظار تكون الـ
الحل ببساطة هو التأكد إن الـ Widget ما زالت موجودة قبل استخدام الـ
التنفيذ بيتوقف مؤقتًا لحد ما العملية تخلص.
وخلال الوقت ده، المستخدم ممكن ينتقل لشاشة تانية، أو الـ Widget الحالية يتم حذفها من شجرة الـ Widget.
بعد انتهاء العملية، الكود الموجود بعد
مثلًا:
هنا فيه احتمال إن الـ Widget اللي كان مرتبط بيها
في الحالة دي، استخدام
الفكرة الأساسية:
بعد
لذلك لا تفترض إن الـ
لو الـ Widget اتشالت أثناء الانتظار، هتكون قيمة
وده مفيد خصوصًا لما تكون الدالة بتستقبل
هنا التأكد من
المهم هو الحالة اللي بيتم فيها استخدام
لو الكود بعد
مثلًا:
هنا مفيش استخدام لـ
مثلًا استخدام
الأفضل إنك تسأل نفسك:
هل الـ Widget ممكن تكون اتشالت أثناء فترة الـ await؟
لو الإجابة نعم، اعمل فحص مناسب باستخدام
الحل المعتاد هو:
داخل
عندما يكون لديك
الفكرة ببساطة: ما تستخدمش الـ BuildContext بعد عملية غير متزامنة إلا بعد التأكد إن الـ Widget ما زالت موجودة.
يمكنك أيضًا مشاهدة شرح سريع للفكرة في الفيديو القصير المرتبط بالموضوع.
BuildContext بعد await، فالمشكلة مش في BuildContext نفسه.المشكلة إن الكود ممكن ينتظر عملية غير متزامنة، وخلال فترة الانتظار تكون الـ
Widget اتشالت من الشاشة. لو استخدمت BuildContext بعدها، ممكن تحاول تتعامل مع Widget لم تعد موجودة.الحل ببساطة هو التأكد إن الـ Widget ما زالت موجودة قبل استخدام الـ
BuildContext.إيه اللي بيحصل بعد await؟
لما تكتب: Code:
await someAsyncOperation(); وخلال الوقت ده، المستخدم ممكن ينتقل لشاشة تانية، أو الـ Widget الحالية يتم حذفها من شجرة الـ Widget.
بعد انتهاء العملية، الكود الموجود بعد
await هيكمل التنفيذ.مثلًا:
Code:
Future loadData() async {
await Future.delayed(const Duration(seconds: 2));
Navigator.of(context).pop();
} context تكون اتشالت قبل انتهاء الثانيتين.في الحالة دي، استخدام
context بعد await ممكن يكون غير آمن.ليه Flutter بتطلع التحذير؟
Flutter عندها lint اسمهuse_build_context_synchronously، وهدفه تنبيهك لما تستخدم BuildContext بعد عملية غير متزامنة.الفكرة الأساسية:
بعد
await، حالة الـ Widget ممكن تكون اتغيرت.لذلك لا تفترض إن الـ
BuildContext ما زال صالحًا لمجرد إنك كنت تستخدمه قبل await.الحل باستخدام mounted
لو أنت داخلState، تقدر تتأكد إن الـ Widget ما زالت موجودة باستخدام mounted: Code:
Future loadData() async {
await Future.delayed(const Duration(seconds: 2));
if (!mounted) return;
Navigator.of(context).pop();
} mounted هي false، وبالتالي الكود هيتوقف قبل استخدام context.الحل باستخدام context.mounted
في الحالات اللي عندك فيهاBuildContext مباشرة، ممكن تستخدم context.mounted: Code:
Future showMessage(BuildContext context) async {
await Future.delayed(const Duration(seconds: 2));
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('تم تحميل البيانات'),
),
);
} BuildContext كـ parameter.مثال عملي مع زر
مثلًا لو عندك زر بيبدأ عملية تحميل وبعدها ينتقل لشاشة تانية: Code:
ElevatedButton(
onPressed: () async {
await loadData();
if (!context.mounted) return;<br><br>Navigator.of(context).push(<br> MaterialPageRoute(<br> builder: (_) => const NextPage(),<br> ),<br>);<br>
},
child: const Text('Continue'),
) context.mounted بيضمن إن الـ Widget المرتبطة بالـ context ما زالت موجودة قبل تنفيذ عملية التنقل.هل لازم أستخدم mounted بعد كل await؟
مش معنى وجودawait إنك لازم تستخدم mounted في كل مرة.المهم هو الحالة اللي بيتم فيها استخدام
BuildContext بعد العملية غير المتزامنة.لو الكود بعد
await لا يستخدم BuildContext أو أي شيء مرتبط بدورة حياة الـ Widget، فغالبًا لا تحتاج لهذا الفحص.مثلًا:
Code:
Future calculateValue() async {
await Future.delayed(const Duration(seconds: 1));
return 100;
} context بعد await، لذلك مشكلة BuildContext غير موجودة في هذا المثال.خطأ شائع
من الأخطاء الشائعة إنك تخفي التحذير بدل ما تعالج السبب.مثلًا استخدام
// ignore لمجرد إسكات الـ lint مش هو الحل الأفضل.الأفضل إنك تسأل نفسك:
هل الـ Widget ممكن تكون اتشالت أثناء فترة الـ await؟
لو الإجابة نعم، اعمل فحص مناسب باستخدام
mounted أو context.mounted قبل استخدام BuildContext.الخلاصة
تحذير Flutter من استخدامBuildContext بعد await موجود لأن الـ Widget ممكن تكون اتشالت أثناء انتظار العملية غير المتزامنة.الحل المعتاد هو:
Code:
if (!mounted) return; State، أو: Code:
if (!context.mounted) return; BuildContext مباشر.الفكرة ببساطة: ما تستخدمش الـ BuildContext بعد عملية غير متزامنة إلا بعد التأكد إن الـ Widget ما زالت موجودة.
يمكنك أيضًا مشاهدة شرح سريع للفكرة في الفيديو القصير المرتبط بالموضوع.

الأسئلة الشائعة
--------------ما هو سبب تحذير use_build_context_synchronously؟
التحذير يظهر عندما يتم استخدامBuildContext بعد await، لأن الـ Widget المرتبطة بهذا الـ context قد تكون أُزيلت أثناء انتظار العملية غير المتزامنة.هل mounted يحل مشكلة BuildContext بعد await؟
نعم، عندما تكون داخلState، يمكنك فحص mounted قبل استخدام context بعد await.ما الفرق بين mounted و context.mounted؟
mounted هي خاصية متاحة داخل State، بينما context.mounted تسمح لك بالتحقق من صلاحية الـ BuildContext نفسه.هل يمكن تجاهل تحذير use_build_context_synchronously؟
يمكن إسكات تحذير الـ lint، لكن الأفضل عادةً معالجة السبب والتأكد من أن الـ Widget أو الـBuildContext ما زال صالحًا قبل استخدامه بعد await.