Einmalig in initState laden
Teil des Abschnitts Daten und Netzwerk der Flutter-Journey von Coddy. Lektion 7 von 27.
Flutter ruft build jedes Mal erneut auf, wenn der Bildschirm neu gezeichnet wird: nach jedem setState, wenn das Telefon gedreht wird und wenn sich ein übergeordnetes Widget ändert. Das kann mehrmals pro Sekunde passieren. build sollte nur den Bildschirm beschreiben und niemals eine Aktion starten.
Ein in build geschriebener fetch-Aufruf wird also bei jedem Neuzeichnen erneut ausgeführt. Jeder Aufruf ist eine neue Anfrage an den Server, und der Bildschirm kann zu einer anderen Antwort springen, obwohl niemand danach gefragt hat:
// eine neue Anfrage bei jedem Neuzeichnen
FutureBuilder<String>(
future: fetch('/tip'),
...
)Erstelle das Future einmal, wenn der Bildschirm geöffnet wird, in initState, und übergib FutureBuilder jedes Mal dasselbe Future:
late Future<String> _tip;
@override
void initState() {
super.initState();
_tip = fetch('/tip');
}initState wird einmal vor dem ersten Aufruf von build ausgeführt. Beginne die Methode mit super.initState();, so wie Flutter es verlangt.
Aufgabe
MittelTippe in der oberen Leiste auf das Herz: Der Tipp ändert sich, weil sich fetch in build befindet. Lade den Tipp einmal:
- Füge dem Zustand
late Future<String> _tip;hinzu - Setze ihn in
initStatemitfetch('/tip') - Übergib dem
FutureBuilder_tip
Probier es selbst
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();
},
),
),
),
);
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Daten und Netzwerk
2Ladebildschirme
Ein Spinner während des LadensFutureBuilder kennenlernenEinmalig in initState ladenDaten per Button neu ladenZum Aktualisieren nach unten ziehen5Datumsangaben und Preise
Datumsangaben mit DateFormatUhrzeiten mit DateFormatPreise mit NumberFormatÜbe selbstständig: Online-Flutter-Compiler