Ошибка флаттера: setState() или markNeedsBuild() вызывается во время сборки

#flutter #state-management

Вопрос:

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

Вот мой код: класс поставщика:

         import 'package:flutter/material.dart';
         class EmpAndState with ChangeNotifier {
         final String empId;
         String stateId;
         EmpAndState({@required this.empId, this.stateId = "1"});
          }

         class EmpsAstates with ChangeNotifier {
         List<EmpAndState> _items = [];
         List<EmpAndState> get items {
         return [..._items];
         }

         void addAll(List<String> empIdes) {
        final eIds = empIdes.map((e) => EmpAndState(empId: e)).toList();
       _items = eIds;
       notifyListeners();
       }


// void addItem(String eId, String stId) {
//   _items.add(EmpAndState(empId: eId, stateId: stId));
//   notifyListeners();
// }

void updateItem(String eId, String stId) {
 _items[_items.indexWhere((es) => es.empId == eId)] =
    EmpAndState(empId: eId, stateId: stId);
  notifyListeners();
   }

 EmpAndState findById(String eId) {
 return _items.firstWhere((es) => es.empId == eId);
 }
 }
 

Класс слушателя:

     import 'package:Attendece/provider/empAstate.dart';
    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    import '../provider/employeeAtypes.dart';

    class ListTileRow extends StatelessWidget {
    static const IconData cancel_outlined =
    IconData(0xe0c9, fontFamily: 'MaterialIcons');

  Widget build(BuildContext context) {
  Employee emp = Provider.of<Employee>(context);
  final empAsta = Provider.of<EmpsAstates>(context);
  final eas = empAsta.findById(emp.employeeId);
 return Row(
  mainAxisSize: MainAxisSize.min,
  mainAxisAlignment: MainAxisAlignment.end,
  children: [
    IconButton(
        icon: eas.stateId == "1"
            ? Icon(Icons.check_circle, color: Color(0xff507ce0))
            : Icon(Icons.check_circle_outline),
        onPressed: () {
          if (eas.stateId != "1") {
            eas.stateId = "1";
          } else {
            eas.stateId = "2";
          }
          emp.notifyListeners();
          empAsta.updateItem(emp.employeeId, eas.stateId);
        }),
    IconButton(
        icon: eas.stateId == "2"
            ? Icon(Icons.clear, color: Colors.red)
            : Icon(Icons.clear),
        onPressed: () {
          if (eas.stateId != "2") {
            eas.stateId = "2";
            emp.notifyListeners();
            empAsta.updateItem(emp.employeeId, eas.stateId);
          } else {
            eas.stateId = "1";
            emp.notifyListeners();
            empAsta.updateItem(emp.employeeId, eas.stateId);
          }
        }),
    IconButton(
        icon: eas.stateId == "3"
            ? Icon(Icons.airline_seat_flat, color: Color(0xff507ce0))
            : Icon(Icons.airline_seat_flat),
        onPressed: () {
          if (eas.stateId != "3") {
            eas.stateId = "3";
            emp.notifyListeners();
            empAsta.updateItem(emp.employeeId, eas.stateId);
          } else {
            eas.stateId = "1";
            emp.notifyListeners();
            empAsta.updateItem(emp.employeeId, eas.stateId);
          }
        }),
    IconButton(
        icon: eas.stateId == "5"
            ? Icon(Icons.home, color: Color(0xff507ce0))
            : Icon(Icons.home),
        onPressed: () {
          if (eas.stateId != "5") {
            eas.stateId = "5";
            emp.notifyListeners();
            empAsta.updateItem(emp.employeeId, eas.stateId);
          } else {
            eas.stateId = "1";
            emp.notifyListeners();
            empAsta.updateItem(emp.employeeId, eas.stateId);
          }
        }),
  ],
);
}
}
 

Ответ №1:

Вам необходимо инициализировать поставщика в точке входа вашего приложения

предоставьте оболочку вокруг InheritedWidget, чтобы сделать их более простыми в использовании и более многоразовыми.

вы не можете получить к нему доступ до его инициализации

  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
      ChangeNotifierProvider<MyProvider>(
            create: (context) => MyProvider()),
       ], child: MaterialApp(....
 

также измените with ChangeNotifier на extends ChangeNotifier

Комментарии:

1. Я делал это раньше, и мой основной урок похож на этот.

2. вместо использования final для использования провайдером var попробуйте запустить flutter clean, а затем повторно запустить приложение

3. Консоль показывает ошибку в классе поставщика, в котором я вызвал notifyListeners() в методе addAll ().