جلب البيانات مرة واحدة في initState
جزء من قسم البيانات والشبكة في رحلة Flutter على Coddy. الدرس 7 من 27.
يستدعي Flutter الدالة build مجددًا في كل مرة يُعاد فيها رسم الشاشة: بعد كل استدعاء لـ setState، وعندما يدور الهاتف، وعندما يتغير عنصر أب. قد يحدث ذلك مرات عديدة في الثانية. ينبغي أن تصف build الشاشة فقط، وألا تبدأ أي عمل مطلقًا.
لذلك، فإن استدعاء fetch المكتوب داخل build يُنفَّذ مجددًا عند كل إعادة رسم. كل تنفيذ هو طلب جديد إلى الخادم، وقد تنتقل الشاشة إلى إجابة مختلفة من دون أن يطلب أحد ذلك:
// طلب جديد عند كل إعادة رسم
FutureBuilder<String>(
future: fetch('/tip'),
...
)أنشئ المستقبل مرة واحدة، عند فتح الشاشة، داخل initState، ومرّر المستقبل نفسه إلى FutureBuilder في كل مرة:
late Future<String> _tip;
@override
void initState() {
super.initState();
_tip = fetch('/tip');
}يُنفَّذ initState مرة واحدة، قبل أول استدعاء لـ build. ابدأه باستخدام super.initState();، كما يطلب Flutter.
التحدي
متوسطاضغط على القلب في الشريط العلوي: ستتغير النصيحة، لأن fetch موجودة في build. حمّل النصيحة مرة واحدة:
- أضف
late Future<String> _tip;إلى الحالة - عيّنها في
initStateباستخدامfetch('/tip') - مرّر
_tipإلىFutureBuilder
جرّب بنفسك
import 'package:flutter/material.dart';
import 'api.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: TipScreen(),
);
}
}
class TipScreen extends StatefulWidget {
const TipScreen({super.key});
@override
State<TipScreen> createState() => _TipScreenState();
}
class _TipScreenState extends State<TipScreen> {
bool liked = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Tip of the Day'),
actions: [
IconButton(
icon: Icon(liked ? Icons.favorite : Icons.favorite_border),
onPressed: () {
setState(() {
liked = !liked;
});
},
),
],
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: FutureBuilder<String>(
future: fetch('/tip'),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
snapshot.data!,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 24),
);
}
return const CircularProgressIndicator();
},
),
),
),
);
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البيانات والشبكة
2شاشات التحميل
مؤشر دائري أثناء التحميلتعرّف على FutureBuilderجلب البيانات مرة واحدة في initStateإعادة تحميل البيانات بزرالسحب للتحديثتدرّب بنفسك: مترجم Flutter عبر الإنترنت