Menu
CoddyTech
flag Ar iconالعربيةdown icon

جلب البيانات مرة واحدة في 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.

challenge icon

التحدي

متوسط

اضغط على القلب في الشريط العلوي: ستتغير النصيحة، لأن 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();
              },
            ),
        ),
      ),
    );
  }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البيانات والشبكة

تدرّب بنفسك: مترجم Flutter عبر الإنترنت