MultiProvider 中的 Consumer 和 context.watch

sen*_*iwa 2 dart flutter flutter-provider

我是第一次尝试 Flutter,对课程有点困惑MultiProvider

问题很简单,但我没有找到解释:

应该什么时候使用Consumer以及什么时候使用context.watch

例如,以我发现的示例应用程序之一为例,我尝试使用两个提供程序来表示两个全局状态、应用程序的主题和状态:

runApp(
  MultiProvider(providers: [
    ChangeNotifierProvider(create: (context) => AppTheme()),
    ChangeNotifierProvider(create: (context) => AppStatus()),
  ],
  child: const MyApp()
  ));
Run Code Online (Sandbox Code Playgroud)

然后应用程序小部件通过以下方式访问主题Consumer

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

  @override
  Widget build(BuildContext context) {
    return Consumer<AppTheme>(
      builder: (context, appTheme, child) {
        // ...
Run Code Online (Sandbox Code Playgroud)

据我了解,现在所有子小部件都将继承提供程序。这样对吗?

那么,我的主页被MyApp类调用时使用Consumer,而是context.watch

@override
Widget build(BuildContext context) {
  final appTheme = context.watch<AppTheme>();
  final appStatus = context.watch<AppStatus>();
  return NavigationView( 
    // ...
Run Code Online (Sandbox Code Playgroud)

它有效,不要误会我的意思,但我只是复制了上面的行appStatus,所以我并没有真正完全理解它。这也是由于我设计了另一个屏幕来访问全局AppStatus状态,但我使用了Consumer如 Flutter 文档所建议的

class _ViewerState extends State<Viewer> {

  @override
  Widget build(BuildContext context) {
    return Consumer<AppStatus>(
      builder: (context, appStatus, child) {
        return ScaffoldPage.scrollable(
          header: const PageHeader(title: Text('Test')),
          children: [
            FilledButton(child: Text("Try ${appStatus.count}"), onPressed: (){ appStatus.increment(); debugPrint('pressed ${appStatus.count}'); }),
            FilledButton(child: Text("Reset"), onPressed: (){ appStatus.reset(); }),
          ]);
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

我有一种感觉,我在这里误用了一些东西,而且我真的不明白幕后发生了什么......

use*_*290 7

context.watch<T>()Consumer<T>做同样的事情。大多数时候context.watch<T>()只是更方便。在某些情况下,context不可用的地方Consumer<T>是有用的。