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

flutter_bloc结合freezed开发时Cubit获取sqflite数据返回值始终为null

问题原因
    1. 未触发数据读取逻辑:按钮的onPressed回调里仅打印了当前状态,从未调用DisplayNoteCubit的getData()方法,数据库读取逻辑全程没有执行,自然拿不到数据。
    1. Cubit的getData()逻辑写反:当前getData()方法仅在状态已经是DisplayNoteState.getData类型时才会执行读库逻辑,但初始状态为DisplayNoteState.initial,所以state.maybeMap只会走orElse分支,读库和emit操作永远不会执行。
    1. 状态更新时机不匹配:就算触发了getData(),读库是异步操作,在点击的同步回调里直接打印旧状态,也拿不到刚读取的新数据。
修复方案

第一步:修正Cubit的getData逻辑

删除原有状态判断逻辑,调用getData时直接读取数据库,再emit新状态:

final DBHelper _db=DBHelper.instance;

class DisplayNoteCubit extends Cubit<DisplayNoteState> {
  DisplayNoteCubit() : super(const DisplayNoteState.initial());
  // 改为异步方法,方便调用时等待执行完成
  Future<void> getData() async {
    final notes = await _db.getAllNotesFormDB();
    emit(DisplayNoteState.getData(notes: notes));
  }
}

第二步:修正按钮点击逻辑

点击时先触发数据读取方法,等待异步执行完成后再打印新状态:

BlocBuilder<DisplayNoteCubit, DisplayNoteState>(
  builder: (context, state) {
    return MaterialButton(
      onPressed: () async {
        // 先触发读数据逻辑,等待执行完成
        await context.read<DisplayNoteCubit>().getData();
        // 状态更新后再打印结果
        if(context.mounted) {
          print( '\n print all Data \n ${context.read<DisplayNoteCubit>().state.maybeMap(
            orElse: () => null, 
            getData: (g) => g.notes
          )}');
        }
      },
      child: const Text("Click Me"),
    );
  },
),

可选优化:页面加载时提前拉取数据

如果需要页面打开就加载数据,可以在页面initState阶段调用getData,后续直接在BlocBuilder中根据状态渲染UI即可:

BlocBuilder<DisplayNoteCubit, DisplayNoteState>(
  builder: (context, state) {
    return state.maybeMap(
      orElse: () => const CircularProgressIndicator(),
      getData: (g) => ListView.builder(
        itemCount: g.notes.length,
        itemBuilder: (context, index) => Text(g.notes[index]['content'].toString()),
      ),
    );
  },
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:45:05