简体   繁体   中英

Unhandled Exception: Bad state: Cannot add new events after calling close - Between screens

I have the next architecture:

ScreenA > ScreenB

/// Here i navigate from ScreenA to ScreenB, so here i create the BlocB that i'm going to use
BlocProvider<BlocB>(
  create: (context) => BlocB(),
  child: const ScreenB(),
),  

ScreenB > ScreenC

await Navigator.of(context).pushReplacementNamed(
  PageNames.screenC,
  arguments: context.read<BlocB>(),
);

/// Here i navigate from ScreenB to ScreenC, so i re-value the BlocB
BlocProvider<BlocB>.value(
  value: (args as BlocB),
  child: const ScreenC(),
),

Here i do the same logic until ScreenD where i'm going to use a BlocListener and do the add event from the BlocB

ScreenC > ScreenD

await Navigator.pushNamed(
  context,
  PageNames.screenD,
  arguments: context.read<BlocB>(),
);

/// Here i navigate from ScreenC to ScreenD, so i re-value the BlocB
BlocProvider<BlocB>.value(
  value: (args as BlocB),
  child: const ScreenD(),
),

The BlocF listener

return BlocListener<BlocF, BlocFState>(
  listener: (context, state) {
     if (state.status.isSuccess) {
        context.read<BlocB>().add(someEvent()); // error
     }
  },
  child: child...

Now, i'm going to use a add event from another Bloc (BlocF for example), now send a status and with its listener, i want to add event from BlocB, but ai have the error:

[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Bad state: Cannot add new events after calling close

I don't know why if i pass through the screens my Bloc

The error message suggests that the BlocB instance being used in the BlocListener of ScreenF is no longer valid. This can happen if the BlocB instance is closed or disposed of when navigating away from ScreenA , and then trying to use it again in ScreenD.

Possible solutions:
  1. Ensure that the BlocB instance is not closed or disposed of when navigating away from ScreenA by using a BlocProvider that is above the entire navigation stack and not just within the individual screens. This way the same BlocB instance is always available throughout the navigation stack.
  2. Pass the BlocB instance as a constructor argument to the next screen, rather than relying on BlocProvider.value to re-create it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM