迁移到 Riverpod 2.0 的完整步骤 (Flutter 3.19)

1. 依赖更新
# pubspec.yaml
dependencies:
  flutter_riverpod: ^2.0.0
  # 移除旧版 provider

2. 导入替换
// 替换所有旧导入
import 'package:flutter_riverpod/flutter_riverpod.dart'; // ✅
// 移除 import 'package:provider/provider.dart'; // ❌

3. Provider 声明重构

旧版 Provider:

final counterProvider = Provider((ref) => Counter());

Riverpod 2.0:

// 使用 Provider 或 StateProvider
final counterProvider = Provider<Counter>((ref) => Counter()); // ✅

// 状态管理推荐方案
final countStateProvider = StateProvider<int>((ref) => 0); // ✅

4. Widget 适配

ConsumerWidget 迁移:

// 旧版
class MyWidget extends ConsumerWidget {
  Widget build(BuildContext context, ScopedReader watch) {...} // ❌
}

// Riverpod 2.0
class MyWidget extends ConsumerWidget {
  Widget build(BuildContext context, WidgetRef ref) { // ✅
    final count = ref.watch(countStateProvider);
    return Text('Count: $count');
  }
}

5. 状态读取方式更新
操作 旧版 Riverpod 2.0
读取状态 context.read(provider) ref.read(provider)
监听状态变化 context.watch(provider) ref.watch(provider)
获取 StateNotifier provider.notifier ref.read(provider.notifier)
6. 状态更新示例
// 按钮事件
FloatingActionButton(
  onPressed: () => ref.read(countStateProvider.notifier).state++, // ✅
);

// 异步状态处理
final userProvider = FutureProvider<User>((ref) async {
  return fetchUser();
});

7. Provider 作用域配置
void main() {
  runApp(
    ProviderScope( // ✅ 必须的顶层包裹
      child: MyApp(),
    ),
  );
}

8. 进阶迁移技巧
  1. StateNotifier 迁移:
// 旧版
class Counter extends StateNotifier<int> {...}
final counterProvider = StateNotifierProvider<Counter>((ref) => Counter()); // ❌

// 新版
final counterProvider = NotifierProvider<Counter, int>(() => Counter()); // ✅

  1. 家族参数处理:
final userProvider = Provider.family<User, String>((ref, userId) {
  return User(id: userId);
});

9. 调试工具配置
// main.dart
void main() {
  runApp(
    ProviderScope(
      observers: [RiverpodDebugger()], // ✅ 添加调试器
      child: MyApp(),
    ),
  );
}

10. 完整迁移示例
// 迁移前 (Provider)
class CounterModel extends ChangeNotifier {
  int _count = 0;
  int get count => _count;
  void increment() {
    _count++;
    notifyListeners();
  }
}

// 迁移后 (Riverpod 2.0)
final counterProvider = NotifierProvider<Counter, int>(() => Counter());

class Counter extends Notifier<int> {
  @override
  int build() => 0;

  void increment() => state++;
}

// 使用
ref.watch(counterProvider); // 读取状态
ref.read(counterProvider.notifier).increment(); // 更新状态

最佳实践:

  1. 优先使用 autoDispose 防止内存泄漏
final tempProvider = StateProvider.autoDispose<int>((ref) => 0);

  1. 复杂逻辑使用 AsyncNotifier
  2. 通过 ref.listen 处理副作用

迁移完成后,Riverpod 2.0 将提供更强的类型安全性和更简洁的代码结构,同时支持热重载状态保持。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐