Настройка провайдера в виджете init не работает - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь установить переменную провайдера, когда виджет инициализируется, чтобы у виджета были соответствующие данные.Я получаю ошибку при этом.Вот код:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      builder: (context) => ListManager(),
      child: MaterialApp(
        title: 'crud-to-do',
        home: Home(), // Home calls ListWidget()
      ),
    );
  }
}

class ListWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final listManager = Provider.of<ListManager>(context);
      listManager.list = [
        ListItem(title: 'myTtitle', description: 'My desc', id: '1324j323e')
      ];

    if (listManager.list.isEmpty) return Text("hey");
    return Text(listManager.list[0].title);
  }
}

Это работает, но я получаю ошибку:

flutter: ══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
flutter: The following assertion was thrown while dispatching notifications for ListManager:
flutter: setState() or markNeedsBuild() called during build.
flutter: This ChangeNotifierProvider<ListManager> widget cannot be marked as needing to build because the
flutter: framework is already in the process of building widgets.  A widget can be marked as needing to be
flutter: built during the build phase only if one of its ancestors is currently building. This exception is
flutter: allowed because the framework builds parent widgets before children, which means a dirty descendant
flutter: will always be built. Otherwise, the framework might not visit this widget during this build phase.
flutter: The widget on which setState() or markNeedsBuild() was called was:
flutter:   ChangeNotifierProvider<ListManager>
flutter: The widget which was currently being built when the offending call was made was:
flutter:   ListWidget
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      Element.markNeedsBuild.<anonymous closure> 
package:flutter/…/widgets/framework.dart:3680
flutter: #1      Element.markNeedsBuild 
package:flutter/…/widgets/framework.dart:3695
flutter: #2      State.setState

Поэтому я попытался обернуть initState вокруг значения listManager.list следующим образом:

@override
void initState() {
  listManager.list = [
        ListItem(title: 'myTtitle', description: 'My desc', id: '1324j323e')
  ];
}

Но я получаю сообщение об ошибке:

На объявление 'initState' нет ссылки.

Что я делаю неправильнооба случая, и как правильно установить provider?

1 Ответ

0 голосов
/ 19 сентября 2019

Внутри вашего метода сборки используйте Provider.of<ListManager>(context, listen: false) для предотвращения перестроения.

По умолчанию listen установлен на true и будет вызывать перестроение при изменении модели, что вызовет исключениеbuild() или initState().

...