Menu
CoddyTech

טעינה חד־פעמית ב־initState

חלק מהיחידה נתונים ורשת במסלול ה-Flutter של Coddy. שיעור 7 מתוך 27.

Flutter קוראת ל־build שוב בכל פעם שהמסך מצויר מחדש: אחרי כל setState, כשהטלפון מסתובב, כשההורה משתנה. זה יכול לקרות פעמים רבות בשנייה. build צריכה רק לתאר את המסך, ולא להתחיל עבודה.

לכן, fetch שנכתבת בתוך build רצה שוב בכל ציור מחדש. כל הרצה היא בקשה חדשה לשרת, והמסך יכול לקפוץ לתשובה אחרת כשאף אחד לא ביקש אותה:

// בקשה חדשה בכל ציור מחדש
FutureBuilder<String>(
  future: fetch('/tip'),
  ...
)

צרו את ה־future פעם אחת, כשהמסך נפתח, בתוך initState, והעבירו ל־FutureBuilder את אותו future בכל פעם:

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 אונליין