Skip to content

BlocBuilder continues to use old cubit instance when the context is updated with a new instance #2127

@jjoelson

Description

@jjoelson

Describe the bug
When injecting a cubit with BlocProvider.value and then building with BlocBuilder, changing the cubit to a new instance does not cause the BlocBuilder to subscribe to state changes in the new cubit.

To Reproduce

My desired use case is to replace the bloc instance in the context when some input changes, automatically closing the old instance:

/// A widget that acts identically to [BlocProvider] except it will close its
/// cubit and recreate it when [input] changes.
class BlocInputProvider<C extends Cubit, Input> extends StatefulWidget {
  final Input input;
  final C Function(BuildContext, Input) create;
  final Widget child;

  BlocInputProvider({
    Key key,
    @required this.input,
    @required this.create,
    @required this.child,
  }) : assert(child != null);

  @override
  _BlocInputProviderState<C, Input> createState() =>
      _BlocInputProviderState<C, Input>();
}

class _BlocInputProviderState<C extends Cubit, Input>
    extends State<BlocInputProvider<C, Input>> {
  C _cubit;

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

    _createCubit();
  }

  @override
  void dispose() {
    super.dispose();

    _cubit.close();
  }

  @override
  void didUpdateWidget(covariant BlocInputProvider<C, Input> oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (widget.input != oldWidget.input) {
      _cubit.close();

      _createCubit();
    }
  }

  @override
  Widget build(BuildContext context) {
    return BlocProvider<C>.value(
      value: _cubit,
      child: widget.child,
    );
  }

  void _createCubit() {
    _cubit = widget.create(context, widget.input);
  }
}

However, BlocBuilder in the subtree doesn't react to the cubit being replaced. Digging into BlocBuilderBase, it looks like it only checks for a new instance of the bloc in didUpdateWidget using context.read, meaning it won't know about the new cubit instance until its configuration changes.

I'm reporting this as a bug, but it's very possible this is the intended behavior and there's a very good reason for it!

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpkg:flutter_blocThis issue is related to the flutter_bloc package

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions