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

Flutter BlocBuilder未读取更新状态引发UnexpectedValueError求助

Flutter Bloc 状态更新问题:BlocBuilder 未读取最新状态导致崩溃

作为flutter_bloc新手,这个问题已经困扰我数周:AccountView中的BlocBuilder无法读取RecordBloc的最新更新状态,BlocObserver显示状态已正确更新,但BlocBuilder仍使用初始空值,进而触发UnexpectedValueError,错误信息为"MicroTypeFailure<String>.invalidString(failedValue: )"。

相关代码逻辑

  • 在AppWidget中通过MultiBlocProvider提供Bloc实例
  • AccountView的initState中添加RecordEvent.initialized事件
  • 构建视图时在BlocBuilder处崩溃

相关代码

AppWidget代码

class AppWidget extends StatelessWidget {
  static const String title = 'Vault Pass';

  const AppWidget({super.key});

  @override
  Widget build(BuildContext context) {
    final _appRouter = getIt<AppRouter>();

    /// PROVIDES ACCESS TO BLOCS TO THE CHILDREN
    return MultiBlocProvider(
      providers: [
        BlocProvider(
            create: (context) =>
                //adds event right away! with ..add()
                getIt<AuthBloc>()..add(const AuthEvent.authCheckRequest())),
        BlocProvider(create: (context) => getIt<RegisterBloc>()),
        BlocProvider(create: (context) => getIt<LoginBloc>()),
        BlocProvider(create: (context) => getIt<RecordBloc>()),
      ],
      child: MaterialApp.router(
        routerDelegate: _appRouter.delegate(),
        routeInformationParser: _appRouter.defaultRouteParser(),
        debugShowCheckedModeBanner: false,
        title: title,
        theme: ThemeData(
            primaryColor: blackJet,
            //TODO: add colors here //splashColor: grey!!!,
            textTheme: GoogleFonts.poppinsTextTheme(Theme.of(context).textTheme),
            colorScheme: ColorScheme.fromSwatch(primarySwatch: materialWhite),
            scaffoldBackgroundColor: blackFull),
      ),
    );
  }
}

AccountView代码

class AccountView extends StatefulWidget {
  final Record record;

  const AccountView({required this.record, Key? key}) : super(key: key);

  @override
  State<AccountView> createState() => _AccountViewState();
}

class _AccountViewState extends State<AccountView> {
  @override
  void initState() {
    context.read<RecordBloc>().add(RecordEvent.initialized(fp.Option.of(widget.record)));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<RecordBloc, RecordState>(
      builder: (context, state) {
        return WillPopScope(
          /// this makes the device button work to go back
          onWillPop: () {
            context.navigateBack();
            return Future.value(false);
          },
          child: Scaffold(
            backgroundColor: Palette.blackFull,
            body: SafeArea(
              child: CustomScrollView(
                slivers: [
                  SliverFillRemaining(
                    hasScrollBody: false,
                    child: Padding(
                      padding: const EdgeInsets.fromLTRB(8, 20, 8, 8),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          //! RECORD TYPE
                          _RecordTypeWidget(value: state.record.type.value.toLowerCase()),
                          const Divider(height: 10, thickness: 1, color: Colors.white),
                          const SizedBox(height: 10),

                          //! RECORD NAME
                          ViewCardWidget(
                              textWidget: {"Record name": state.record.recordName.get()},
                              cardHeight: 12),

                          //! Title
                          Padding(
                            padding: const EdgeInsets.fromLTRB(15, 15, 10, 2),
                            child: Text("Credentials", style: bodyText(12, Palette.greySpanish)),
                          ),

                          //! RECORD LOGIN AND PASSWORD
                          ViewCardWidget(textWidget: {
                            "Login": state.record.loginRecord.get(),
                            "Password": state.record.passwordRecord.get()
                          }, cardHeight: 24),

                          //! URL
                          ViewCardWidget(
                              textWidget: {"Url": state.record.url.get()}, cardHeight: 12),

                          //! DESCRIPTION
                          ViewCardWidget(
                              textWidget: {"Description": state.record.description.get()},
                              cardHeight: 12),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
            floatingActionButtonLocation: FloatingActionButtonLocation.miniEndFloat,
            floatingActionButton: _SpeedDialFabWidget(recordId: state.record.id),
          ),
        );
      },
    );
  }
}

栈跟踪信息

======== Exception caught by widgets library =======================================================
The following UnexpectedValueError was thrown building BlocBuilder<RecordBloc, RecordState>(dirty, dependencies: [_InheritedProviderScope<RecordBloc?>], state: _BlocBuilderBaseState<RecordBloc, RecordState>#77787):
"Encountered a Error at an unrecoverable point. Failure was: MicroTypeFailure<String>.invalidString(failedValue: )"

The relevant error-causing widget was: 
  BlocBuilder<RecordBloc, RecordState> BlocBuilder:file:///D:/_workspace/flutter/vault_pass/lib/presentation/view/records/account/account_view.dart:37:12
When the exception was thrown, this was the stack: 
#0      MicroType.get.<anonymous closure> (package:vault_pass/domain/microtypes/microtype.dart:15:30)
#1      Left.match (package:fpdart/src/either.dart:592:72)
#2      Either.fold (package:flutter/src/widgets/framework.dart:4690:5)
#3      MicroType.get (package:vault_pass/domain/microtypes/microtype.dart:15:18)
#4      _AccountViewState.build.<anonymous closure> (package:vault_pass/presentation/view/records/account/account_view.dart:64:83)
#5      BlocBuilder.build (package:flutter_bloc/src/bloc_builder.dart:90:57)
#6      _BlocBuilderBaseState.build (package:flutter_bloc/src/bloc_builder.dart:166:21)
#7      StatefulElement.build (package:flutter/src/widgets/framework.dart:5080:27)
#8      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4968:15)
#9      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5133:11)
#10     Element.rebuild (package:flutter/src/widgets/framework.dart:4690:5)
#11     StatefulElement.update (package:flutter/src/widgets/framework.dart:5156:5)
#12     Element.updateChild (package:flutter/src/widgets/framework.dart:3660:15)
#13     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4993:16)
#14     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5133:11)
#15     Element.rebuild (package:flutter/src/widgets/framework.dart:4690:5)
#16     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2743:19)
#17     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:863:21)
#18     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:381:5)
#19     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1289:15)
#20     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1218:9)
#21     SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:942:7)
#25     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)
(elided 3 frames from class _Timer and dart:async-patch)
====================================================================================================

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:07:18