提供者和消费者问题

时间:2021-03-28 17:17:34

标签: flutter dart provider

我对 Flutter 还很陌生,我正在尝试通过提供程序包来提高我的状态管理技能。我在加载我的类别和通知听众何时显示我的类别小部件而不是我的 modalprogressHUD 时遇到了一些困难

这是 MyApp 类:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<LoginProvider>(
          create: (_) => LoginProvider(),
        ),
        ChangeNotifierProvider<CatergoryProvider>(
          create: (_) => CatergoryProvider(),
        ),
        ChangeNotifierProvider<RegistrationProvider>(
          create: (_) => RegistrationProvider(),
        ),
        ChangeNotifierProvider<QuestionProvider>(
          create: (_) => QuestionProvider(),
        ),
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        debugShowCheckedModeBanner: false,
        theme: ThemeData.dark().copyWith(
          primaryColor: Colors.teal,
        ),
        initialRoute: DashBoard.id,
        routes: {
          WelcomeScreen.id: (context) => WelcomeScreen(),
          DashBoard.id: (context) => DashBoard(),
          QuizzPage.id: (context) => QuizzPage()
        },
      ),
    );
  }
}

我的 CatergoryProvider 类:

import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:quizz_app/models/catergory.dart';
import 'package:quizz_app/services/services.dart';

class CatergoryProvider with ChangeNotifier {
  List<Catergory> catergory;
  String errorMessage;
  bool loading = false;

  Future<bool> fetchCatergory() async {
    setLoading(true);

    await Service(url: "https://quizapp1234.herokuapp.com/kategori")
        .fetchCatergory()
        .then((data) {
      if (data.statusCode == 200) {
        print('success');
        Iterable l = json.decode(data.body);
        setCatergory(
            List<Catergory>.from(l.map((data) => Catergory.fromJson(data))));
        setLoading(false);
      } else {
        Map<String, dynamic> result = json.decode(data.body);
        setMessage(result['message']);
      }
    });
    return isList();
  }

  bool isLoading() {
    return loading;
  }

  void setLoading(value) {
    loading = value;
    notifyListeners();
  }

  void setCatergory(value) {
    catergory = value;
    notifyListeners();
  }

  void setMessage(value) {
    errorMessage = value;
    notifyListeners();
  }

  List<Catergory> getList() {
    return catergory;
  }

  String getMessage() {
    return errorMessage;
  }

  bool isList() {
    return catergory != null ? true : false;
  }
}

这里是我包装我想要通知消费者的地方:

  Consumer<CatergoryProvider>(
    builder: (context, catergory, child) {
      catergory.fetchCatergory();
      catergories = catergory.getList();
      return catergory.isLoading()
          ? ModalProgressHUD(
              opacity: 0,
              inAsyncCall:
                  Provider.of<CatergoryProvider>(context).isLoading(),
              child: Scaffold())
          : catergoryPage(catergories, context);
    },
  ),

我的调试控制台:

════════ Exception caught by foundation library ════════════════════════════════
setState() or markNeedsBuild() called during build.
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by foundation library ════════════════════════════════
setState() or markNeedsBuild() called during build.
════════════════════════════════════════════════════════════════════════════════

发生的异常:

Exception has occurred.
FlutterError (A CatergoryProvider was used after being disposed.
Once you have called dispose() on a CatergoryProvider, it can no longer be used.)

1 个答案:

答案 0 :(得分:2)

builder: 内的消费者上,您调用 fetchCatergory,在 fetchCatergory 内调用 notifyListeners() 的方法调用函数,每次调用 notifyListeners() 时,{ {1}} 被召回,导致无限循环

仅当 builder: 返回 null 且 catergory.fetchCatergory() 为 false 时才尝试包装 getList()

代码:

isLoading()