Intégrations tierces

Avec Provider

Ajouter Qora à une app Provider existante pour spécialiser la gestion de l'état serveur tout en conservant Provider pour l'état UI et l'injection de dépendances.

Provider et ChangeNotifier sont efficaces pour l'état UI et l'injection de dépendances. La gestion des données serveur introduit un boilerplate répétitif dans chaque notifier : isLoading, error, gardes de cache manuelles et gestion des retries incohérente.

Qora prend en charge cette responsabilité spécifique. Provider conserve tout le reste.


Le problème avec ChangeNotifier pour les données serveur

Un notifier de récupération de données typique :

lib/providers/user_provider.dart
class UserNotifier extends ChangeNotifier {
  User? data;
  bool isLoading = false;
  Object? error;
  int? _loadedId;

  Future<void> fetchUser(int id) async {
    if (_loadedId == id && data != null) return; // cache manuel, pas de TTL, pas de SWR
    isLoading = true;
    error = null;
    notifyListeners();
    try {
      data = await UserApi.getUser(id);
      _loadedId = id;
    } catch (e) {
      error = e; // pas de retry, pas de backoff
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }
}
lib/user_screen.dart
Consumer<UserNotifier>(
  builder: (context, notifier, _) {
    if (notifier.isLoading) return const CircularProgressIndicator();
    if (notifier.error != null) return ErrorWidget('${notifier.error}');
    if (notifier.data == null) {
      notifier.fetchUser(userId); // effet de bord dans build, cycle de vie fragile
      return const SizedBox.shrink();
    }
    return UserCard(notifier.data!);
  },
)

Ce pattern est écrit identiquement pour chaque appel API. Il manque aussi : stale-while-revalidate, refetch en arrière-plan au focus/reconnexion, déduplication des requêtes et support hors ligne.


Après : laisser Qora gérer les données serveur

lib/main.dart
final qoraClient = QoraClient(
  config: const QoraClientConfig(
    defaultOptions: QoraOptions(staleTime: Duration(minutes: 5)),
  ),
);

runApp(
  MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_) => ThemeNotifier()),
      ChangeNotifierProvider(create: (_) => AuthNotifier()),
    ],
    child: QoraScope(
      client: qoraClient,
      lifecycleManager: FlutterLifecycleManager(qoraClient: qoraClient),
      connectivityManager: FlutterConnectivityManager(),
      child: const MyApp(),
    ),
  ),
);
lib/user_screen.dart
QoraBuilder<User>(
  queryKey: ['users', userId],
  fetcher: () => UserApi.getUser(userId),
  builder: (context, state, fetchStatus) => switch (state) {
    Success(:final data) => UserCard(data),
    Loading() => const CircularProgressIndicator(),
    Failure(:final error) => ErrorWidget('$error'),
    Initial() => const SizedBox.shrink(),
  },
)

La version Qora supprime les flags de chargement manuels, les notifications de notifier et les gardes de cache personnalisées. Retry, déduplication des requêtes, revalidation en arrière-plan et comportement SWR sont intégrés.

Le troisième argument du builder fetchStatus distingue FetchStatus.fetching de FetchStatus.paused en conditions hors ligne. Utiliser cet état pour afficher un indicateur d'attente de connexion plutôt qu'un spinner de chargement.


Division des responsabilités

ResponsabilitéGarder dans ProviderDéplacer vers Qora
Données récupérées depuis une API (users, products, feeds)QoraBuilder + fetcher:
Mutations (create, update, delete)QoraMutationBuilder
État UI (onglet sélectionné, modal ouvert, valeurs de formulaire)ChangeNotifier
Session d'authentification (token en mémoire)ChangeNotifier
Injection de dépendances (services, repositories)Provider / ChangeNotifierProvider

Correspondance des APIs

Pattern ProviderÉquivalent Qora
ChangeNotifier + méthode fetch()QoraBuilder avec fetcher:
Consumer + ternaire sur isLoading / error / dataswitch (state) sur QoraState
if (data != null) return manuelstaleTime dans QoraOptions
ChangeNotifierProvider (couche données)QoraScope
notifyListeners() après écritureclient.invalidate(key)

Checklist

  • Ajouter qora_flutter à pubspec.yaml et exécuter flutter pub get
  • Imbriquer QoraScope à l'intérieur de la racine MultiProvider existante (pas un remplacement)
  • Identifier les classes ChangeNotifier qui ne font que fetcher et émettre loading/error/data et les remplacer par QoraBuilder (fetcher:, builder à 3 arguments)
  • Remplacer les ternaires loading/error/data de Consumer par switch (state)
  • Remplacer les gardes de cache manuelles par staleTime
  • Remplacer notifyListeners() post-écriture par client.invalidate(key)
  • Conserver les entrées ChangeNotifierProvider pour l'état UI, l'auth et l'injection de dépendances

Voir aussi

Copyright © 2026