Introducción al problema

Recuerda que en el capítulo 4 repasamos como podías administrar los estados efímeros y aplicativos, por favor si no lo tienes en el radar revisa el contenido del capítulo 4.

<aside> 👾 Repasa los conceptos antes de aplicarlos (enlace).

</aside>

En este momento nuestra aplicación tiene un gran problema y es el siguiente :

Cada vez que necesitamos la entidad usuario la compartimos entre pantallas como un atributo de entrada. Por ejemplo en el siguiente código:

import 'package:flutter/material.dart';
import 'package:weinflu_app/config/app_routes.dart';
import 'package:weinflu_app/models/user.dart';

class NewPage extends StatelessWidget {
  const NewPage({super.key});

  @override
  Widget build(BuildContext context) {
    final userData = User(name: 'Weincoders', age: 24);
    return Scaffold(
      appBar: AppBar(
        title: const Text('New Page'),
      ),
      body: Center(
          child: TextButton(
        child: Text('hola todo anda bien'),
        onPressed: () =>
            Navigator.of(context).pushReplacementNamed(AppRoutes.otherPage, arguments: userData),
      )),
    );
  }
}

En el código anterior evidentemente tenemos que crear la identidad userData y compartirla la pantalla otherPage. Y si desde otherPage se lo queremos enviar a otra pantalla tendríamos que volverla a compartir como argumento. Peor aun si es necesaria dos pantallas adelante, tendríamos que compartir esta identidad en pantallas que no la van a necesitar solo para poder compartir la información al final.

Para solucionar esto, existe una forma genial y es utilizando el Inherited Widget.

Recuerda que lo ideal es únicamente gestionar a través de el los estados aplicativos y en este caso el usuario es un excelente candidato.

Creando un proveedor de la información de usuario

Cuando alguien te suministra información lo solemos llamar proveedor. Por tanto, necesitamos un proveedor de información de usuario, veamos el siguiente código:

import 'package:flutter/material.dart';
import 'package:weinflu_app/models/user.dart';

class UserProvider extends InheritedWidget {
  //Información que deseamos compartir
  final User userData;
  const UserProvider({super.key, required super.child, required this.userData});

  //Obtener la información solo utilizando el contexto
  static UserProvider of(BuildContext context) {
    return context.findAncestorWidgetOfExactType<UserProvider>()!;
  }

  @override
  bool updateShouldNotify(UserProvider oldWidget) =>
      oldWidget.userData.name != userData.name ? true : false;
}

Es interesante ver como la definición extiende del InheritedWidget. Recordemos que los InheritedWidgets solo admiten información inmutable. Por lo tanto, ¿Como es posible que nos sirva para compartir y actualizar información el InheritedWidget? Porque la definición es estática pero no sus atributos 🤯.

Supongamos la siguiente clase para usuario:

class User {
  String name;
  User({required this.name});
}

En este caso podríamos a actualizar el nombre aunque el objeto sea final 👀.

Otro punto a detallar es las siguiente líneas de código:

 //Obtener la información solo utilizando el contexto
  static UserProvider of(BuildContext context) {
    return context.findAncestorWidgetOfExactType<UserProvider>()!;
  }