【问题标题】:Why i am getting error while calling api with provider?为什么在使用提供程序调用 api 时出现错误?
【发布时间】:2021-08-18 00:00:19
【问题描述】:

我正在调用一个 API 并使用提供程序保存它的响应,以便我可以从我的 Flutter 应用程序中的任何位置访问。用于存储响应的模型是

class Album with ChangeNotifier {
      final String id;
      final List<String> categoriesId;
      final String title;
      final String imageUrl;

      Album({this.id, this.categoriesId, this.title, this.imageUrl});

      factory Album.fromJson(Map<String, dynamic> json) {
            List<dynamic> res = json['category_list'];
            List<String> cats = [];
            res.forEach((tx) {
                cats.add(tx.toString());
            });
            return Album(
                id: json['id'].toString(),
                categoriesId: cats,
                title: json['name'],
                imageUrl: json["image"],
            );
      }
}

虽然函数调用端点是,

String albumUrl = "http://192.168.227.102:9000/static/album.json";

Future<List<Album>> fetchAnime(BuildContext context) async {
  List<Album> resAlbum = [];
  try {
     final response = await http.get(Uri.parse(albumUrl));
     if (response.statusCode == 200) {
       List<dynamic> result = jsonDecode(response.body)['album'];
       result.forEach((tx) {
          Album test = Anime.fromJson(tx as Map<String, dynamic>);
          resAlbum.add(test);
       });
     }
   } catch (e) {
     print(e);
 }
  return resAlbum;
}

模型Album的提供者是,

class AlbumProvider with ChangeNotifier {
  List<Album> _items = [];

  void getPostData(context) async {
     bool loading = true;
     if (this._items.isNotEmpty) {
        this._items = await fetchAlbum(context);
     }
     loading = false;
     notifyListeners();
  }
}

使用这个提供者的视图是,

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
   void initState() {
     Provider.of<AlbumProvider>(context, listen: false).getPostData(context);
     super.initState();
   }
   @override
   Widget build(BuildContext context) {
       List<Album> albumData = Provider.of<AlbumProvider>(context).allitems;
       return Scaffold(
         appBar: AppBar(
           title: Text(
             'Home Screen',
           ),
         ),
         body:albumData.isEmpty
            ?Text("we are fetching data")
            :Text("fetching complete")
         )
     }
  }

当我运行应用程序时出现以下错误,

在为 AlbumProvider 发送通知时抛出了以下断言: 在构建期间调用 setState() 或 markNeedsBuild()。

这个 _InheritedProviderScope 小部件不能被标记为需要构建,因为框架已经在构建小部件的过程中。仅当其祖先之一当前正在构建时,小部件才能在构建阶段标记为需要构建。这个例外是允许的,因为框架在子组件之前构建父小部件,这意味着将始终构建脏后代。否则,框架可能不会在此构建阶段访问此小部件。 调用 setState() 或 markNeedsBuild() 的小部件是:_InheritedProviderScope

出现此错误的原因是什么?如何消除此错误?

【问题讨论】:

  • alitems 变量在哪里?

标签: flutter dart flutter-provider


【解决方案1】:

这是因为,当你打电话时

Provider.of<AlbumProvider>(context, listen: false).getPostData(context);

来自 HomePage 的 initState 方法,然后调用下面的方法

  void getPostData(context) async {
     bool loading = true;
     if (this._items.isNotEmpty) {
        this._items = await fetchAlbum(context);
     }
     loading = false;
     notifyListeners();
  }

这个函数正在调用notifiyListeners(); 问题是您正在监听 HomePage 的 build 方法中对 AlbumProvider 的更改。

 List<Album> albumData = Provider.of<AlbumProvider>(context).allitems;

所以最终,initState 正在调用 getPostData,而 notifyListeners() 将尝试在构建完成之前重建小部件树。

您应该FutureBuilder 而不是在initState 方法中调用getPostData()

【讨论】:

    猜你喜欢
    • 2021-07-20
    • 2020-06-17
    • 1970-01-01
    • 2021-02-07
    • 2015-04-25
    • 1970-01-01
    • 2021-01-01
    • 2019-09-22
    • 1970-01-01
    相关资源
    最近更新 更多