Flutter Riverpod - Utilisation de read () dans la méthode de construction

Oct 07 2020

Supposons que je veuille initialiser un champ de texte en utilisant la initialValue:propriété sur a TextFormFieldet que ma valeur initiale provienne d'un fournisseur. J'ai lu dans la documentation qu'appeler read()depuis l'intérieur de la méthode de construction est considéré comme une mauvaise pratique, mais appeler des gestionnaires est bien (comme onPressed). Je me demande donc si c'est bien d'appeler read depuis la initialValuepropriété comme indiqué ci-dessous?

Réponses

2 AlexHartford Oct 07 2020 at 23:25

Non, vous devez utiliser useProvidersi vous utilisez des crochets, ou un ConsumerWidget/ Consumersi vous ne l' utilisez pas.

La différence étant que le initialValuechamp fait partie de la méthode de construction et, comme vous l'avez dit, onPressedest un gestionnaire, en dehors de la méthode de construction.

Un aspect essentiel des fournisseurs est l'optimisation des reconstructions à mesure que les valeurs changent. L'utilisation context.readdans la méthode de génération annule cet avantage car vous n'écoutez pas la valeur fournie.

L' utilisation context.readest fortement recommandé dans les fonctions anonymes ( onChanged, onPressed, onTap, etc.) parce que ces fonctions sont en train de récupérer la valeur fournie au moment où la fonction est exécutée. Cela signifie que la fonction s'exécutera toujours avec la valeur actuelle de ce fournisseur, sans avoir à écouter le fournisseur. Les autres méthodes de lecture des fournisseurs utilisent un auditeur qui est plus cher et inutile dans le cas des fonctions anonymes.

Dans votre exemple, vous vouliez définir initialValueun fichier TextFormField. Voici comment vous pouvez utiliser hooks_riverpod et flutter_hooks pour y parvenir.

class HooksExample extends HookWidget {
  const HooksExample({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      initialValue: useProvider(loginStateProv).email,
    );
  }
}

Et pour les lecteurs qui préfèrent ne pas utiliser de hooks:

class ConsumerWidgetExample extends ConsumerWidget {
  const ConsumerWidgetExample({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    return TextFormField(
      initialValue: watch(loginStateProv).email,
    );
  }
}

Ou:

class ConsumerExample extends StatelessWidget {
  const ConsumerExample({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Consumer(
      builder: (context, watch, child) {
        return TextFormField(
          initialValue: watch(loginStateProv).email,
        );
      },
    );
  }
}

La principale différence est que Consumerne reconstruira que ses enfants car ils sont les seuls à se fier aux données fournies.