简体   繁体   English

如何使用 BLOC 处理 Flutter 小部件重建?

[英]How to handle Flutter widget rebuilding with BLOC?

In regards to Flutter's way to rebuild widgets when navigating between routes, there is this issue: Pages on Navigator stack rebuild when a new page is pushed where the dev team and others provided these interesting insights:关于 Flutter 在路由之间导航时重建小部件的方式,存在以下问题:当推送新页面时,Navigator 堆栈上的页面会重建,其中开发团队和其他人提供了这些有趣的见解:

  1. About this reported behavior in the issue itself : 关于问题本身中报告的此行为

This is working as intended.这是按预期工作的。 In general, you should assume that all widgets can rebuild at any time, that they don't is mostly just an optimization.通常,您应该假设所有小部件都可以随时重建,而它们不能重建主要只是一种优化。 [...] [...]

  1. Further (re)explained here : 进一步(重新)解释here

You should generally assume that every widget will be rebuilt every frame, and design your build methods to be idempotent [...]您通常应该假设每个小部件将在每一帧重新构建,并将您的构建方法设计为幂等 [...]

  1. When asked how to handle fetching data in build(context) : 当被问及如何处理在build(context)中获取数据时

you'll need to restructure your code so that the data is not fetched again [...].您需要重新构建代码,以免再次获取数据 [...]。


I am using BLoC to fetch remote data.我正在使用 BLoC 来获取远程数据。 For example, in my HomePage :例如,在我的HomePage中:

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<HomeBloc, HomeState>(
      bloc: sl.get()..add(const GetHomeEvent()), // `sl` from package `GetIt`, a dependency injector
      builder: (context, state) {
        return AnimatedSwitcher(
          duration: const Duration(milliseconds: 300),
          child: state.join(
            (initial) => const EmptyHome(),
            (loading) => const LoadingHome(),
            (success) => LoadedHome(homeEntity: success.homeEntity),
            (failure) => FailedHome(errorMessage: failure.message),
          ),
        );
      },
    );
  }

As you can read, I build a BlocBuilder and upon its instantiation, I asked the HomeBloc to fetch data:如您所见,我构建了一个BlocBuilder并在实例化时要求HomeBloc获取数据:

HomeBloc() : super(HomeState.initial()) {
  on<GetHomeEvent>((event, emit) async {
     print('load home event request');
     // code to load home and notify of result via `emit()`
    );
  });

The log load home event request gets printed multiple times as I navigate in and out from my home page.当我从主页导航进出时,日志load home event request会被打印多次。

How should I go about and prevent unnecessarily reloading the home?我应该如何防止不必要的重装首页?

  • Should I simply cache it via a local variable?我应该简单地通过局部变量缓存它吗?
  • How to handle refresh properly (eg hit F5 in the web browser)?如何正确处理刷新(例如在 web 浏览器中按 F5)?

build method is such a method which will be executed frequently. build 方法就是这样一个会被频繁执行的方法。 For screen pages who need to fetch some data, it is prefereed to create stateful widget instead of stateless.对于需要获取一些数据的屏幕页面,最好创建有状态的小部件而不是无状态的。 And then you should add event on bloc inside initState method instead of build.然后你应该在 initState 方法中的 bloc 上添加事件而不是 build。 Don't forget to delete..({event}) in build methos.不要忘记在构建方法中删除..({event})。 In that way you will get rid off problem with unnecessary API requests.这样,您将摆脱不必要的 API 请求的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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