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.
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>()!;
}