La aplicación Flutter se bloquea después de convertir el proveedor 3 a 4

8

Traté de actualizar mi aplicación Flutter para usarla Provider 4.0.1hoy y el siguiente código falló al asignar un valor a nulo.

Aquí está el código que estoy intentando convertir. Solo cambié SingleChildCloneableWidgeta la SingleChildStatelessWidgetque compilé OK.

import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';

List<SingleChildStatelessWidget> providers = [
  ...independentServices,
  ...dependentServices,
  ...uiConsumableProviders
];

List<SingleChildStatelessWidget> independentServices = [
  Provider.value(value: Api()),
  Provider.value(value: Tbl()),
  Provider.value(value: Bill()),
  Provider.value(value: Sale()),
  Provider.value(value: Category()),
  Provider.value(value: Menu()),
];

List<SingleChildStatelessWidget> dependentServices = [
  ProxyProvider<Api, AuthenticationService>(
    update: (context, api, authenticationService) => AuthenticationService(api: api),
  ),
];

List<SingleChildStatelessWidget> uiConsumableProviders = [
  StreamProvider<User>(
    create: (context) => Provider.of<AuthenticationService>(context, listen: false).user,
  ),
    lazy: false
];

Lo implementé así:

StreamController<User> _userController = StreamController<User>();
Stream<User> get user => _userController.stream;

El accidente ocurrió en esta línea:

Future<void> _setFixedLanguageStrings(BuildContext context) async {

 User _user = Provider.of<User>(context);

 _user.homeString = await translate(context, 'Home');

El getter 'idioma' fue llamado nulo. Receptor: nulo

Esto funcionaba bien, Provider 3.0.3pero obviamente necesito hacer más.

Mi código original vino de este tutorial .

editar: Solucioné ese problema agregando lazy: falseel método de creación del proveedor de flujo, pero luego otro error más adelante en este código.

Future<String> translate(BuildContext context, _term) async {

  final String _languageCode = Provider.of<User>(context).language;

que produjo este error:

Una excepción ha ocurrido. _AssertionError ('paquete: proveedor / src / provider.dart': Aserción fallida: línea 213 pos 7: 'context.owner.debugBuilding || listen == false || _debugIsInInheritedProviderUpdate': Intenté escuchar un valor expuesto con el proveedor, desde fuera del árbol de widgets.

Es probable que esto sea causado por un controlador de eventos (como un botón onPressed) que llamó a Provider.of sin pasar listen: false.

Para solucionarlo, escriba: Provider.of (contexto, escuche: falso);

No es compatible porque puede reconstruir sin sentido el widget asociado al controlador de eventos, cuando el árbol de widgets no se preocupa por el valor. )

Agregué listen: falsea la línea anterior que parece haber solucionado ese problema, sin embargo, el siguiente proveedor que intenté usar produjo este error:

Intenté escuchar un valor expuesto con el proveedor, desde fuera del árbol de widgets.

Es probable que esto sea causado por un controlador de eventos (como un botón onPressed) que llamó a Provider.of sin pasar listen: false.

Para solucionarlo, escriba: Provider.of (contexto, escuche: falso);

No es compatible porque puede reconstruir sin sentido el widget asociado al controlador de eventos, cuando el árbol de widgets no se preocupa por el valor. 'package: provider / src / provider.dart': Afirmación fallida: línea 213 pos 7: 'context.owner.debugBuilding || escuchar == falso || _debugIsInInheritedProviderUpdate '

¿Debo ir ahora a todas las instancias donde llamo a un proveedor y agrego listen: false? Necesito que alguien me explique qué ha cambiado y por qué, ya que soy bastante nuevo en Flutter y los documentos son escasos Provider. Muchas veces llamo al Proveedor en mi código y este último error no devolvió una ubicación de código.

¿ listen: falseAhora siempre se requiere cuando no era antes o me he perdido algo más? Estoy empezando a agregar listen: false a cada llamada para crear una instancia de una variable de proveedor y parece estar funcionando, pero ¿es este el enfoque correcto? ¿Debo agregar listen: falsea cada llamada Provider.ofy llamarlo un día?

El error indica que la aplicación intentó escuchar un valor fuera del árbol de widgets, pero no creo que sea así, ya que lo llamo dentro del método de compilación de widgets. Si este error es correcto, de alguna manera todos mis proveedores están fuera del árbol de widgets. El código ha estado funcionando bien durante un par de meses, los errores de escucha solo aparecieron en esta actualización.

Markhorrocks
fuente
Tengo el mismo problema al actualizar. La cuestión es, ¿qué pasa si puedo o no cambiar el árbol de widgets? Estoy retrocediendo
Dpedrinha

Respuestas:

3

Tengo el mismo "problema", si agrego en listen: falsetodas partes llamo al proveedor, el problema se ha ido pero no sé si esa es la solución correcta ...

dukaric1991
fuente
Me pregunto por qué listen: falseno es el predeterminado SingleChildStatelessWidget?
Markhorrocks
no hay ningún error con listen: false, pero la interfaz de usuario no se actualiza, por lo que se necesita algo más para que funcione
Shakle
1

listen : false se llama cuando los datos no actualizan nada en la interfaz de usuario y se deben usar, como eliminar todas las tarjetas en un widget cuando se hace clic en el botón.

Para más información, lea este go_to_link

Khalil Khalil
fuente
0

listen:true ser el predeterminado es lógico.

No especifica dentro de un controlador de eventos que no sea lógico.listen: false

Además, 4.1.0 de alguna manera tendrá una alternativa más corta a Provider.of:

context.read<T>() // Provider.of<T>(context, listen: false)
context.watch<T>() // Provider.of<T>(context)
Jaime
fuente