【问题标题】:Why is the BlocBuilder never called when bloc is not set explicitly为什么未显式设置 bloc 时从未调用 BlocBuilder
【发布时间】:2020-08-08 08:09:10
【问题描述】:

这是一个 Flutter 计数器应用的示例。我用这样的 Bloc 实例化 Counter:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Counter(CounterBloc()),
    );
  }
}

下面的代码可以正常工作。调度事件并调用“builder”方法。

class Counter extends StatelessWidget {
  final Bloc bloc;

  const Counter(this.bloc, {Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProvider<CounterBloc>(
      create: (context) => bloc,
      child: CounterPage(),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocBuilder<CounterBloc, int>(
        builder: (context, count) => CountView(count),
      ),
      floatingActionButton: AddButton(
          action: () => BlocProvider.of<CounterBloc>(context)
              .add(CounterEvent.increment)),
    );
  }
}

下面的代码不起作用。事件被调度,但构建器从未被调用。

class Counter extends StatelessWidget {
  final Bloc bloc;

  const Counter(this.bloc, {Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProvider<CounterBloc>(
      create: (context) => bloc,
      child: Scaffold(
        body: BlocBuilder<CounterBloc, int>(
          builder: (context, count) => CountView(count),
        ),
        floatingActionButton: AddButton(
            action: () => BlocProvider.of<CounterBloc>(context)
                .add(CounterEvent.increment)),
      ),
    );
  }
}

我发现我可以在“BlocBuilder”上设置属性“bloc”,但我认为这不是必需的。 为什么会有不同的行为?

【问题讨论】:

    标签: flutter bloc flutter-bloc


    【解决方案1】:

    我相信来自不工作 sn-p 的 CounterEvent.increment 不会被调度,而是会抛出错误 BlocProvider.of() called with a context ...,因为您在提供 bloc 的地方使用相同的 context

    此代码有效,因为它是 BlocProvider 之后的新 context

    class Counter extends StatelessWidget {
      final Bloc bloc;
    
      const Counter(this.bloc, {Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return BlocProvider<CounterBloc>(
          create: (context) => bloc,
          child: Builder(
            builder: (context) => Scaffold(
              body: BlocBuilder<CounterBloc, int>(
                builder: (context, count) => CountView(count),
              ),
              floatingActionButton: AddButton(
                action: () => BlocProvider.of<CounterBloc>(context)
                    .add(CounterEvent.increment),
              ),
            ),
          ),
        );
      }
    }
    

    此代码也有效,因为我们显式使用构造函数中的 bloc 实例,而不是调用 BlocProvider.of() 并使用通过 BlocProvider 提供的 bloc 实例。

    class Counter extends StatelessWidget {
      final Bloc bloc;
    
      const Counter(this.bloc, {Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return BlocProvider<CounterBloc>(
          create: (context) => bloc,
          child: Scaffold(
            body: BlocBuilder<CounterBloc, int>(
              bloc: bloc,
              builder: (context, count) => CountView(count),
            ),
            floatingActionButton: AddButton(
              action: () => bloc.add(CounterEvent.increment),
            ),
          ),
        );
      }
    }
    

    上面的两个 sn-ps 都可以工作,但这不是“正确”的方式。

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          home: Counter(
            CounterBloc(), // <=() You need a work around to dispose this instance
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-25
      • 2020-07-20
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2018-02-27
      • 2021-02-19
      • 2019-07-10
      • 1970-01-01
      相关资源
      最近更新 更多