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

Widget因initState中API返回空值报错,不想用FutureBuilder求解

解决不用FutureBuilder时API调用结果展示的空值错误

你推测的有误,Widget的build方法是在initState执行之后才会触发,但fetchAlbum是异步函数——initState调用它后不会等待网络请求完成,会直接继续执行后续逻辑。这导致第一次build时myAlbum还是null,你用myAlbum!.title强制解包就会抛出"Unexpected null value"错误。

要解决这个问题,需要做两个关键修改:

  • 在异步请求完成并更新myAlbum后,调用setState通知Widget重新构建,展示最新数据
  • 在build方法里根据myAlbum的状态,分别渲染加载状态、数据内容或错误提示

修改后的完整代码:

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

class Album {
  final int userId;
  final int id;
  final String title;

  const Album({
    required this.userId,
    required this.id,
    required this.title,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
    );
  }
}

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Album? myAlbum;
  String? errorMessage;

  Future<void> fetchAlbum() async {
    try {
      final response = await http
          .get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));

      if (response.statusCode == 200) {
        setState(() {
          myAlbum = Album.fromJson(jsonDecode(response.body));
          errorMessage = null;
        });
      } else {
        throw Exception('Failed to load album');
      }
    } catch (e) {
      setState(() {
        errorMessage = e.toString();
      });
    }
  }

  @override
  void initState() {
    fetchAlbum();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Fetch Data Example'),
        ),
        body: Center(
          child: Builder(
            builder: (context) {
              if (errorMessage != null) {
                return Text(errorMessage!);
              }
              if (myAlbum == null) {
                return const CircularProgressIndicator();
              }
              return Text(myAlbum!.title);
            },
          ),
        ),
      ),
    );
  }
}

关键修改说明

  • 新增errorMessage变量,用于捕获并展示请求失败的异常信息
  • fetchAlbum中所有状态更新都包裹在setState内,确保Widget能感知到数据变化并重建
  • build方法通过条件判断,依次展示错误提示、加载指示器、最终数据,彻底避免空值强制解包的风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 06:25:28