riverpod-codegen-and-hooks

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Riverpod — Code generation and hooks

Riverpod — 代码生成与hooks

Code generation

代码生成

Code generation is optional in Riverpod. It changes the syntax for defining providers: you write an annotated function or class and the generator produces the provider. Use it if you already use code generation (e.g. Freezed, json_serializable); otherwise the extra build step may not be worth it. See riverpod-getting-started for setup (build_runner, riverpod_generator).
在Riverpod中,代码生成是可选的。它改变了定义provider的语法:你只需编写带有注解的函数或类,生成器就会自动创建对应的provider。如果你已经在使用代码生成工具(如Freezed、json_serializable),可以考虑使用它;否则额外的构建步骤可能得不偿失。如需配置,请查看riverpod-getting-started(涉及build_runner、riverpod_generator)。

Benefits

优势

  • Clearer syntax: no manual provider type (Provider vs FutureProvider etc.); Riverpod infers it.
  • Parameters: any parameters (named, optional, defaults) instead of a single family parameter.
  • Stateful hot-reload for Riverpod code.
  • Better debugging via generated metadata.
  • 语法更简洁:无需手动指定provider类型(如Provider、FutureProvider等);Riverpod会自动推断。
  • 参数更灵活:支持任意参数(命名参数、可选参数、默认参数),而非单一的family参数。
  • Riverpod代码支持有状态热重载。
  • 通过生成的元数据实现更优的调试体验。

Syntax

语法

Functional provider (sync):
dart

String example(Ref ref) {
  return 'foo';
}
Class-based provider (sync, with methods for side effects):
dart

class Example extends _$Example {
  
  String build() => 'foo';
  // Add methods to mutate state
}
Async: Use
Future
/
FutureOr
/
Stream
; async functions get AsyncValue and loading/error handling automatically. Auto-dispose: On by default with codegen. Disable with
@Riverpod(keepAlive: true)
.
dart

String example1(Ref ref) => 'foo';

(keepAlive: true)
String example2(Ref ref) => 'foo';
Parameters: Add parameters to the function (consistent == required):
dart

Future<User> fetchUser(Ref ref, {required int userId}) async {
  final json = await http.get('api/user/$userId');
  return User.fromJson(json);
}
Manual equivalent would be
FutureProvider.autoDispose.family<User, int>(...)
. See riverpod-providers and riverpod-family for concepts.

函数式provider(同步):
dart

String example(Ref ref) {
  return 'foo';
}
基于类的provider(同步,支持副作用方法):
dart

class Example extends _$Example {
  
  String build() => 'foo';
  // Add methods to mutate state
}
异步场景:使用
Future
/
FutureOr
/
Stream
;异步函数会自动获得AsyncValue以及加载/错误处理能力。自动销毁:代码生成模式下默认开启。可通过
@Riverpod(keepAlive: true)
禁用。
dart

String example1(Ref ref) => 'foo';

(keepAlive: true)
String example2(Ref ref) => 'foo';
参数:为函数添加参数(一致性要求 == 必填):
dart

Future<User> fetchUser(Ref ref, {required int userId}) async {
  final json = await http.get('api/user/$userId');
  return User.fromJson(json);
}
手动实现的等效代码为
FutureProvider.autoDispose.family<User, int>(...)
。相关概念可查看riverpod-providers和riverpod-family。

Hooks

Hooks

Hooks come from [flutter_hooks] (separate from Riverpod). They are for local widget state (e.g. TextEditingController, AnimationController) and can replace StatefulWidget or builder nesting. Use them only if you want hooks; they are not required for Riverpod. Newcomers should avoid hooks at first.
Hooks来自[flutter_hooks](独立于Riverpod)。它们用于管理本地组件状态(如TextEditingController、AnimationController),可替代StatefulWidget或嵌套builder。仅当你需要hooks时才使用它们;Riverpod并不强制要求使用。新手建议先避免使用hooks。

Using hooks and Riverpod together

Hooks与Riverpod结合使用

You need both flutter_hooks and hooks_riverpod. Then either:
Option 1: HookConsumerWidget — One base class that supports both hooks and ref:
dart
class Example extends HookConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final counter = useState(0);
    final value = ref.watch(myProvider);
    return Text('Hello $counter $value');
  }
}
Option 2: HookConsumer — Builder that combines HookBuilder + Consumer (works with flutter_riverpod only if you nest them; hooks_riverpod provides HookConsumer):
dart
return HookConsumer(
  builder: (context, ref, child) {
    final counter = useState(0);
    final value = ref.watch(myProvider);
    return Text('Hello $counter $value');
  },
);
Option 3: Nest
Consumer
and
HookBuilder
(no hooks_riverpod needed).
你需要同时引入flutter_hookshooks_riverpod。然后可选择以下方式之一:
方案1:HookConsumerWidget — 同时支持hooks和ref的基类:
dart
class Example extends HookConsumerWidget {
  
  Widget build(BuildContext context, WidgetRef ref) {
    final counter = useState(0);
    final value = ref.watch(myProvider);
    return Text('Hello $counter $value');
  }
}
方案2:HookConsumer — 结合了HookBuilder与Consumer的构建器(若仅使用flutter_riverpod则需嵌套两者;hooks_riverpod提供了HookConsumer):
dart
return HookConsumer(
  builder: (context, ref, child) {
    final counter = useState(0);
    final value = ref.watch(myProvider);
    return Text('Hello $counter $value');
  },
);
方案3: 嵌套
Consumer
HookBuilder
(无需hooks_riverpod)。

Rules of hooks

Hooks使用规则

  • Use hooks only in the build method of a widget that extends HookWidget (or HookConsumerWidget).
  • Do not use hooks conditionally or in loops; call order must be stable.
See riverpod-consumers for Ref in widgets and the official docs for full codegen/hooks details.
  • 仅在继承自HookWidget(或HookConsumerWidget)的组件的build方法中使用hooks。
  • 不要在条件语句或循环中使用hooks;调用顺序必须保持稳定。
如需了解组件中Ref的相关内容,请查看riverpod-consumers;代码生成与hooks的完整细节请参考官方文档。