riverpod最基本例子:在一个组件里更新状态,在另一个组件里获取更新的数据

发布于:2025-06-13 ⋅ 阅读:(23) ⋅ 点赞:(0)

下面是一个完整的例子,演示如何在 Riverpod 中:

  1. 在一个组件(WidgetA)中更新状态
  2. 在另一个组件(WidgetB)中获取更新后的状态

我们将使用 riverpod + flutter_riverpod,并基于最新的 Riverpod 2.0 语法(推荐使用代码生成 @riverpod)。


1. 定义 Provider

首先,创建一个状态管理 Provider(使用 @riverpod 代码生成)。

counter_provider.dart
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'counter_provider.g.dart';

// 定义一个 Counter 状态管理类

class Counter extends _$Counter {
  // 初始状态
  
  int build() => 0;

  // 更新状态的方法
  void increment() => state++;
}

运行代码生成:

dart run build_runner watch

这会生成 counter_provider.g.dart,包含一个全局可用的 counterProvider


2. 在 WidgetA 中更新状态

创建一个按钮组件,点击时调用 increment() 更新状态。

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

class WidgetA extends ConsumerWidget {
  const WidgetA({super.key});

  
  Widget build(BuildContext context, WidgetRef ref) {
    return ElevatedButton(
      onPressed: () {
        // 通过 ref 读取 Counter 并调用方法更新状态
        ref.read(counterProvider.notifier).increment();
      },
      child: const Text('Increment Counter'),
    );
  }
}

3. 在 WidgetB 中获取状态

另一个组件监听 counterProvider 的状态变化,并实时显示最新值。

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

class WidgetB extends ConsumerWidget {
  const WidgetB({super.key});

  
  Widget build(BuildContext context, WidgetRef ref) {
    // 监听 counterProvider 的状态变化
    final counter = ref.watch(counterProvider);

    return Text(
      'Current Count: $counter',
      style: Theme.of(context).textTheme.headlineMedium,
    );
  }
}

4. 整合到主页面

将两个组件放在同一个页面中测试。

main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'widget_a.dart';
import 'widget_b.dart';

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Riverpod Example')),
        body: const Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              WidgetB(), // 显示状态
              SizedBox(height: 20),
              WidgetA(), // 更新状态
            ],
          ),
        ),
      ),
    );
  }
}

效果

  • 点击 WidgetA 的按钮时,Counter 状态会递增。
  • WidgetB 会自动刷新并显示最新的计数器值。

关键点说明

  1. ref.read() vs ref.watch()

    • ref.read():一次性读取状态(适合触发方法,如按钮点击)。
    • ref.watch():监听状态变化并自动重建组件(适合显示数据)。
  2. .notifier

    • 通过 ref.read(counterProvider.notifier) 获取 Counter 实例,才能调用其方法(如 increment())。
  3. ProviderScope

    • 必须在应用的根节点包裹 ProviderScope,这是 Riverpod 的核心上下文。

通过这个例子,你可以清晰看到 Riverpod 的状态更新跨组件共享状态的流程。