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

Flutter FutureBuilder持续处于ConnectionState.waiting状态问题求助

解决Flutter FutureBuilder一直停在waiting状态及数组越界问题

先梳理你代码里的几个关键问题:

  1. FutureBuilder的future重复执行导致无限循环
    你在build方法里直接写future: fetchData(),每次页面重建(比如setState触发)都会重新调用fetchData,而fetchData里的setState又会触发build,形成死循环,所以ConnectionState一直处于waiting。
  2. fetchData没有返回值,FutureBuilder无法获取异步结果
    你声明了Future<dynamic>但没有return任何数据,还通过setState维护外部变量three,这违背了FutureBuilder的设计逻辑——它应该直接使用future返回的快照数据,不需要额外维护状态变量。
  3. 直接访问数组索引导致越界
    初始时three是空数组,three[1]必然触发索引越界错误,必须先判断数据是否加载完成且数组长度足够。

修复后的完整代码

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class DartPad extends StatefulWidget {
  const DartPad({Key? key}) : super(key: key);

  @override
  State<DartPad> createState() => _DartPadState();
}

class _DartPadState extends State<DartPad> {
  // 将future存为成员变量,避免每次build重复执行请求
  late Future<List<dynamic>> _fetchDataFuture;

  Future<List<dynamic>> fetchData() async {
    var sheetID = '1j7sYExCP0etGw_LoxqYTFRrjwHmJv73SHzC26jbtpH4';
    var sheetTab = 'daftar';
    var url = Uri.parse('https://opensheet.elk.sh/$sheetID/$sheetTab');
    final response = await http.get(url);
    
    // 直接解析并返回数据,无需setState
    return json.decode(response.body) as List<dynamic>;
  }

  @override
  void initState() {
    // 在initState中初始化future,只执行一次网络请求
    _fetchDataFuture = fetchData();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        centerTitle: true,
        title: const Text('Dartpad'),
      ),
      body: FutureBuilder<List<dynamic>>(
        // 使用预先初始化的future,避免重复请求
        future: _fetchDataFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: Text('Loading....'));
          } else if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
            return const Center(child: Text('没有数据'));
          } else {
            final dataList = snapshot.data!;
            
            // 方式1:展示单个数据(索引1的nama)
            // return Center(child: Text(dataList[1]['nama'] ?? '无名称'));
            
            // 方式2:循环展示所有数据(推荐)
            return ListView.builder(
              itemCount: dataList.length,
              itemBuilder: (context, index) {
                final item = dataList[index];
                return ListTile(
                  title: Text(item['nama'] ?? '无名称'),
                  subtitle: Text(item['alamat'] ?? ''), // 替换为你需要的其他字段
                );
              },
            );
          }
        },
      ),
    );
  }
}

关键修改说明

  • 将future存为成员变量:在initState中初始化_fetchDataFuture,确保网络请求只执行一次,避免build时重复触发请求。
  • fetchData返回解析后的数据:不再依赖setState更新外部变量,让FutureBuilder直接通过snapshot获取异步结果。
  • 完善状态判断逻辑:依次处理waiting、error、无数据的情况,最后再处理成功加载的数据,彻底避免数组越界。
  • 循环展示数据:用ListView.builder遍历所有数据,既安全又满足你展示全部内容的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:01:38