You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter无状态ConsumerWidget中使用Riverpod FutureProvider?

解决方案

1. 修复productsListProvider未定义错误

在product_grid.dart文件顶部导入fake_products_repository.dart:

import 'fake_products_repository.dart';

这是因为productsListProvider定义在另一个文件中,必须通过导入才能在当前文件识别到。

2. 修正ProductsLayoutGrid的使用与响应数据解析

当前代码存在两个问题:一是ProductsLayoutGrid作为带参数的Widget,不能直接传入类型,必须实例化并传递参数;二是你当前拿到的是http.Response原始响应,需要解析为可用的产品数据。

第一步:定义产品模型

先创建一个产品数据类,用于解析接口返回的JSON:

// 可将此代码添加到fake_products_repository.dart或单独的model文件中
class Product {
  final int id;
  final String name;
  final String imageUrl;

  Product({required this.id, required this.name, required this.imageUrl});

  // 从JSON数据转换为Product实例
  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      id: json['id'],
      name: json['name'],
      imageUrl: json['imageUrl'],
    );
  }
}

第二步:修改productsListProvider返回解析后的产品列表

更新fake_products_repository.dart中的productsListProvider,让它直接返回解析好的产品列表(需导入dart:convert):

import 'dart:convert';

final productsListProvider = FutureProvider<List<Product>>((ref) async {
  final repository = ref.watch(productsRepositoryProvider);
  final response = await repository.fetchProductsList();
  
  // 处理响应状态码并解析数据
  if (response.statusCode == 200) {
    final List<dynamic> jsonData = jsonDecode(response.body);
    return jsonData.map((item) => Product.fromJson(item)).toList();
  } else {
    throw Exception('加载产品失败,状态码:${response.statusCode}');
  }
});

第三步:修正ProductsGrid中的Widget构建逻辑

更新ProductsGrid的build方法,正确实例化ProductsLayoutGrid并传递产品数据:

@override
Widget build(BuildContext context, WidgetRef ref) {
  final productsListValue = ref.watch(productsListProvider);

  return productsListValue.when(
    loading: () => const Center(child: CircularProgressIndicator()),
    error: (err, stack) => Center(child: Text('错误:$err')),
    data: (products) => ProductsLayoutGrid(
      itemCount: products.length,
      itemBuilder: (context, index) {
        final product = products[index];
        // 这里返回单个产品的UI组件,示例用Card展示
        return Card(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Image.network(product.imageUrl, height: 80),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(product.name),
              ),
            ],
          ),
        );
      },
    ),
  );
}

3. 单独测试fetchProductsList函数

如果只想测试这个请求函数,无需依赖Provider,可以直接在任意地方调用:

// 示例:在按钮点击事件或initState中调用
void testProductFetch() async {
  final repo = ProductsRepository();
  final response = await repo.fetchProductsList();
  print('请求状态码:${response.statusCode}');
  print('响应内容:${response.body}');
}

内容的提问来源于stack exchange,提问作者Mohammed M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 00:32:32