Menu
CoddyTech

ConsumerWidget 与 ref.watch

本课属于 Coddy Flutter 学习旅程的“状态管理”单元。第 17 课,共 27 课。

任何 widget 只要能获取 ref,就可以读取 provider。要为它提供 ref,需要改两处:

  • 将 extends StatelessWidget 改为 extends ConsumerWidget。
  • 给 build 添加第二个参数 WidgetRef ref。
class CityName extends ConsumerWidget {
  const CityName({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final city = ref.watch(cityProvider);
    return Text(city);
  }
}

ref.watch(cityProvider) 会为你提供 provider 的值,这里是文本 Lisbon。每当这个值发生变化时,widget 都会重新构建。如果没有 ref.watch,cityProvider 就只是 provider 本身,而不是它的值。

每个需要某个值的 widget 都可以在自身所在的位置这样获取它。不需要通过构造函数向下传递任何内容,也不需要通过 context 来查找它。

challenge icon

挑战

简单

CityName 和 Temperature 显示的是占位内容。让它们读取文件顶部的提供器:

  • 将它们都改为 ConsumerWidget。
  • CityName 显示 cityProvider 的值。
  • Temperature 显示 temperatureProvider 的值,后面跟着 °C,字号保持不变。

亲手试试

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final cityProvider = Provider((ref) => 'Lisbon');
final temperatureProvider = Provider((ref) => 21);

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: const CityName()),
        body: const Center(child: Temperature()),
      ),
    );
  }
}

class CityName extends StatelessWidget {
  const CityName({super.key});

  @override
  Widget build(BuildContext context) {
    return const Text('City');
  }
}

class Temperature extends StatelessWidget {
  const Temperature({super.key});

  @override
  Widget build(BuildContext context) {
    return const Text('0°C', style: TextStyle(fontSize: 64));
  }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

状态管理中的所有课

自己练习: Flutter 在线编译器