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

Flutter升级后调用snapshot.data的length、map方法报错如何解决

问题原因

你遇到的报错是Flutter升级到空安全版本后,类型校验更严格 + 代码逻辑错误共同导致的,核心问题有3个:

  1. FutureBuilder传参错误:你在initState已经调用了fetchData(widget.medicineCatUniqId),但build方法里FutureBuilder的future参数又传了fetchData(medicineSubCategoryApi),初始状态下medicineSubCategoryApi是null,相当于请求参数错误,接口自然返回不了有效数据。而且future直接写方法调用的话,每次页面重绘都会重复发起请求,属于严重的逻辑错误。
  2. 类型不匹配:旧版Flutter没有强空安全校验,snapshot.data默认是dynamic类型可以任意调用方法,升级后FutureBuilder没有指定泛型,snapshot.data会被推断为Object?类型,Object本身没有length和map方法,直接调用就会报错。
  3. 你贴的第二份测试代码存在语法错误:代码里残留了上一个版本的括号,语法不合法也会导致编译/运行报错。

修复方案

按如下步骤修改代码即可解决:

  1. 在State中定义专门的Future变量存储请求任务,避免重复发起请求
  2. 给FutureBuilder指定泛型,明确返回数据是List类型
  3. 调用方法前做类型校验和空判断

修改后可运行完整代码

class _TabPageState extends State<TabPage> {
  late Future<List> _fetchDataFuture; // 定义Future变量存储请求任务

  @override
  void initState() {
    super.initState();
    // 初始化时只发起一次请求,参数用widget传进来的medicineCatUniqId
    _fetchDataFuture = fetchData(widget.medicineCatUniqId);
  }

  Future<List> fetchData(var medicineCatUniqId) async {
    var api = Uri.parse('$baseUrl/productSubCatApi.php?a2rTokenKey=$a2rTokenKey&pcat=$medicineCatUniqId');
    var response = await http.get(api);
    print("medicineCatApiLnk " + api.toString());
    print("medicineCat" + response.body);
    List medicineSubCategoryApi = jsonDecode(response.body);
    print("medicineCatString" + medicineSubCategoryApi.toString());
    return medicineSubCategoryApi;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FutureBuilder<List>(
          future: _fetchDataFuture, // 直接传已经创建好的Future,不会重复请求
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              }
              // 明确snapshot.data是List类型,直接调用方法不会报错
              List data = snapshot.data!;
              print(data.length.toString());
              print(data.toString());
            
              return DefaultTabController(
                length: data.length,
                child: Scaffold(
                  appBar: AppBar(
                    title: const Text('Tabbed AppBar'),
                    bottom: TabBar(
                      isScrollable: true,
                      tabs: data
                          .map<Widget>((choice) => Tab(
                                text: choice['psubCatName'],
                              ))
                          .toList(),
                    ),
                  ),
                  body: TabBarView(
                    physics: NeverScrollableScrollPhysics(),
                    children: data.map<Widget>((choice) {
                      return Padding(
                        padding: const EdgeInsets.all(20.0),
                        child: ChoicePage(
                          choice: choice,
                        ),
                      );
                    }).toList(),
                  ),
                ),
              );
            } else {
              return const Text('Loading');
            }
          }),
    );
  }
}


class ChoicePage extends StatelessWidget {
  const ChoicePage({Key? key, this.choice}) : super(key: key);
  final Map choice; // 明确类型,避免空安全报错

  @override
  Widget build(BuildContext context) {
    final TextStyle? textStyle = Theme.of(context).textTheme.headline4;
    return Card(
      color: Colors.white,
      child: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Text(
              choice['psubCatName'],
              style: textStyle,
            ),
          ],
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 23:36:03