Menu
CoddyTech

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.

challenge icon

Défi

Moyen

Appuie 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 initState avec fetch('/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();
              },
            ),
        ),
      ),
    );
  }
}
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur Flutter en ligne