FutureBuilder est un widget dans Flutter qui reconstruit automatiquement son interface en fonction de l’état actuel d’AsyncSnapshot obtenu à partir d’un Future fourni. Contrairement à l’appel manuel de setState après await, FutureBuilder offre une approche déclarative : il s’abonne au Future lors du premier rendu et appelle la fonction builder à chaque changement d’état — chargement, erreur ou données prêtes. Selon la Référence de l’API Flutter (2026), FutureBuilder est particulièrement utile pour charger des données depuis le réseau, lire dans une base de données et toutes les opérations asynchrones où l’interface doit afficher un indicateur de chargement, un message d’erreur ou un contenu prêt.
Points Clés
FutureBuilder est un widget intégré de Flutter du package widgets qui prend un Future
Contrairement à StreamBuilder, qui fonctionne avec des flux de données (Stream), FutureBuilder est conçu pour des opérations asynchrones uniques : requête HTTP, lecture de fichier, requête de base de données. FutureBuilder gère lui-même l’abonnement au Future : lors de la première construction, il démarre le Future et suit son achèvement. Lorsque le widget est détruit, FutureBuilder n’annule pas le Future — c’est la responsabilité du développeur.
Selon le Flutter Cookbook (2026), FutureBuilder est recommandé pour les cas où une opération asynchrone s’exécute une fois lors de l’initialisation de l’écran. Pour les opérations récurrentes ou les flux de données, utilisez StreamBuilder. Les deux widgets suivent le même modèle d’interface réactive, mais FutureBuilder est optimisé pour les requêtes uniques.
L’implémentation interne de FutureBuilder s’abonne au Future en utilisant Future.then et catchError. Au démarrage, FutureBuilder définit connectionState sur ConnectionState.waiting et appelle le builder avec des données vides. En cas de succès, connectionState passe à ConnectionState.done avec les données. En cas d’erreur, snapshot.error est rempli avec l’objet d’erreur. Chaque changement déclenche une reconstruction du widget.
AsyncSnapshot est un objet conteneur que FutureBuilder passe à la fonction builder à chaque changement d’état. Il contient toutes les informations sur le statut actuel de l’opération asynchrone : si le chargement est en cours, quelles données ont été reçues ou si une erreur s’est produite. Comprendre AsyncSnapshot est la clé pour construire correctement l’interface avec FutureBuilder.
| Propriété | Type | Description |
|---|---|---|
| connectionState | ConnectionState | État actuel de la connexion (none, waiting, active, done) |
| data | T? | Données reçues du Future (null jusqu’à la fin ou en cas d’erreur) |
| error | Object? | Objet d’erreur si le Future s’est terminé avec une exception |
| hasData | bool | true si data n’est pas null et connectionState est ConnectionState.done |
| hasError | bool | true si le Future s’est terminé avec une erreur |
L’énumération ConnectionState définit l’étape d’une opération asynchrone. None — état initial lorsque le Future n’a pas encore été démarré (rarement utilisé, généralement lors de la première construction sans initialData). Waiting — le Future est en cours d’exécution, données pas encore reçues. Active — utilisé uniquement par StreamBuilder pour les flux avec données partielles. Done — le Future est terminé, les données sont disponibles via snapshot.data ou l’erreur via snapshot.error.
La gestion correcte de tous les états d’AsyncSnapshot dans la fonction builder est une exigence obligatoire pour le code de production. Si vous ne gérez pas l’état waiting, l’utilisateur verra un écran vide pendant le chargement. Si vous ne gérez pas hasError, l’utilisateur recevra une Exception sans explication. Le modèle recommandé : vérifier hasError → vérifier hasData → afficher le chargement par défaut.
FutureBuilder peut être utilisé dans plusieurs modèles standards, chacun résolvant une tâche spécifique. Examinons les principaux scénarios : chargement des données à l’initialisation, chargement avec cache, requêtes parallèles et gestion des erreurs avec réessai.
Le modèle le plus courant — FutureBuilder dans la méthode build d’un StatefulWidget ou StatelessWidget. Le Future est passé depuis initState ou créé directement dans build. Il est important de ne pas créer le Future dans la méthode build lors de chaque reconstruction — cela entraînerait des requêtes répétées. Utilisez un Future stocké dans un champ du State.
Pour éviter les requêtes répétées, FutureBuilder peut être combiné avec CachedNetworkImage ou un cache local. Après le premier chargement, les données sont sauvegardées en mémoire ou dans SharedPreferences, et FutureBuilder affiche instantanément les données en cache tout en les actualisant depuis le réseau en parallèle. Cela améliore l’expérience utilisateur grâce à une réponse instantanée.
Selon pub.dev (2026), la mise en cache est particulièrement pertinente pour les images et les listes de données. FutureBuilder avec CachedNetworkImageProvider affiche automatiquement une image en cache, et en son absence — un indicateur de chargement suivi du fichier téléchargé.
FutureBuilder et la gestion manuelle de l’état via setState sont deux approches pour l’interface asynchrone dans Flutter. Chacune a ses avantages et ses limites. Le choix dépend de la complexité de l’écran et du nombre d’opérations asynchrones.
FutureBuilder gagne en simplicité : vous n’avez pas besoin de déclarer des champs pour l’état de chargement, les données et l’erreur — tout est géré via AsyncSnapshot. Il est idéal pour les écrans simples avec une opération asynchrone (une requête HTTP, une lecture de base de données). Cependant, avec 5+ opérations asynchrones sur un seul écran, FutureBuilder crée un embranchement excessif — aboutissant à une « pyramide » de FutureBuilders imbriqués.
setState avec des indicateurs d’état manuels offre plus de contrôle et de lisibilité pour une logique complexe. Pour les écrans avec plusieurs requêtes dépendantes (charger l’utilisateur → charger ses commandes → charger les détails de la commande), il est préférable d’utiliser setState avec ChangeNotifier ou Bloc. Selon le Guide de Gestion d’État Flutter (2026), pour les scénarios complexes, Riverpod ou Bloc sont recommandés plutôt que FutureBuilder, car ils offrent une meilleure séparation de la logique et de la présentation.
Considérons un exemple pratique de FutureBuilder pour charger une liste d’utilisateurs depuis une API REST. Le code démontre le traitement correct des trois états d’AsyncSnapshot : chargement, erreur et données prêtes.
class UserListPage extends StatefulWidget {
const UserListPage({super.key});
@override
State<UserListPage> createState() => _UserListPageState();
}
class _UserListPageState extends State<UserListPage> {
final Future<List<User>> usersFuture = UserRepository().fetchUsers();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Utilisateurs')),
body: FutureBuilder<List<User>>(
future: usersFuture,
builder: (context, AsyncSnapshot<List<User>> snapshot) {
if (snapshot.hasError) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.error_outline, size: 48, color: Colors.red),
const SizedBox(height: 16),
Text('Erreur : ${snapshot.error}'),
],
),
);
}
if (snapshot.hasData) {
final users = snapshot.data!;
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(backgroundImage: NetworkImage(users[index].avatarUrl)),
title: Text(users[index].name),
subtitle: Text(users[index].email),
);
},
);
}
return const Center(child: CircularProgressIndicator());
},
),
);
}
}
Dans l’exemple, FutureBuilder gère les trois états. En cas d’erreur, une icône avec un message d’erreur est affichée. En cas de chargement réussi — une ListView avec des avatars et des noms. Pendant le chargement — un CircularProgressIndicator. Le Future est déclaré comme un champ de classe, ce qui empêche les appels répétés lors des reconstructions. Ce modèle couvre 90% des scénarios d’utilisation de FutureBuilder dans les applications mobiles.
Foire Aux Questions
FutureBuilder appelle le builder à chaque changement d’état du Future : la première fois à la création (connectionState : none ou waiting), la deuxième fois à la fin (connectionState : done). Si le widget parent est reconstruit, FutureBuilder est également reconstruit. Pour éviter des appels répétés, assurez-vous que le Future est créé en dehors de la méthode build — sinon chaque appel de build créera un nouveau Future.
Stockez le Future dans un champ de StatefulWidget (dans initState) ou utilisez la mémoïsation. Si le Future est créé à l’intérieur de la méthode build, chaque appel de build créera un nouveau Future, et FutureBuilder redémarrera l’opération asynchrone. Pour StatelessWidget, utilisez le paquet cached_future ou des widgets keep-alive pour que le Future s’exécute une seule fois indépendamment des reconstructions.
FutureBuilder est conçu pour des opérations asynchrones uniques (une requête HTTP, une lecture de base de données). StreamBuilder fonctionne avec des flux de données pouvant émettre plusieurs valeurs dans le temps (chat, mises à jour de prix, géolocalisation). StreamBuilder supporte ConnectionState.active pour les données partielles, tandis que FutureBuilder ne supporte que waiting et done.
Pour plusieurs Futures parallèles, utilisez Future.wait et passez le résultat à un seul FutureBuilder. Future.wait prend une liste de Futures et retourne un Future — lorsque tous les Futures sont terminés, le builder reçoit un tableau de résultats. Pour les requêtes séquentielles, utilisez une chaîne Future.then dans un seul Future ou des FutureBuilders imbriqués (moins lisible). Une alternative est le paquet riverpod avec AsyncValue pour plusieurs états asynchrones.
FutureBuilder n’annule pas le Future automatiquement. Pour annuler, utilisez CancelableOperation du paquet async ou un mécanisme personnalisé via un indicateur cancelled dans State. Définissez l’indicateur dans dispose(), et vérifiez-le après la fin du Future avant d’appeler setState. Alternativement, utilisez le paquet riverpod avec AutoDispose, qui annule automatiquement les opérations asynchrones en quittant l’écran.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi