Charger une seule fois dans initState
Fait partie de la section Données et réseau du Journey Flutter de Coddy. Leçon 7 sur 27.
Flutter appelle de nouveau build chaque fois que l’écran est redessiné : après chaque setState, lorsque le téléphone pivote, lorsqu’un parent change. Cela peut se produire plusieurs fois par seconde. build ne doit que décrire l’écran, et ne jamais lancer de traitement.
Ainsi, un fetch écrit dans build s’exécute de nouveau à chaque redessin. Chaque exécution envoie une nouvelle requête au serveur, et l’écran peut passer à une réponse différente alors que rien ne l’a demandée :
// une nouvelle requête à chaque redessin
FutureBuilder<String>(
future: fetch('/tip'),
...
)Crée la future une seule fois, à l’ouverture de l’écran, dans initState, et transmets cette même future à FutureBuilder à chaque fois :
late Future<String> _tip;
@override
void initState() {
super.initState();
_tip = fetch('/tip');
}initState s’exécute une seule fois, avant le premier build. Commence par super.initState();, comme Flutter le demande.
Défi
MoyenAppuie sur le cœur dans la barre supérieure : le conseil change, car fetch se trouve dans build. Charge le conseil une seule fois :
- ajoute
late Future<String> _tip;à l’état - initialise-le dans
initStateavecfetch('/tip') - passe
_tipàFutureBuilder
Essayez vous-même
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();
},
),
),
),
);
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Données et réseau
2Écrans de chargement
Un indicateur pendant le chargementDécouvrir FutureBuilderCharger une seule fois dans initStateRecharger les données avec un boutonTirer pour actualiserEntraînez-vous par vous-même : Compilateur Flutter en ligne