跳到主要内容
Declarative programming

Declarative programming

Write business logic in a manner similar to Stateless widgets.
Have your network requests to automatically recompute when necessary and make your logic easily reusable/composable/maintainable.

Easily implement common UI patterns

Easily implement common UI patterns

Using Riverpod, common yet complex UI patterns such as "pull to refresh"/ "search as we type"/etc... are only a few lines of code away.

Tooling ready

Tooling ready

Riverpod enhances the compiler by having common mistakes be a compilation-error. It also provides custom lint rules and refactoring options. It even has a command line for generating docs.

Features

  • Declarative programming
  • Native network requests support
  • Automatic loading/error handling
  • Compile safety
  • Type-safe query parameters
  • Test ready
  • Work in plain Dart (servers/CLI/...)
  • Easily combinable states
  • Built-in support for pull-to-refresh
  • Custom lint rules
  • Built-in refactorings
  • Hot-reload support
  • Logging
  • Websocket support
  • Documentation generator

任意位置声明共享状态

不再需要在你的 main.dart 和UI文件之间来回跳转。
将共享状态的代码放在它所属的位置上,无论是放在独立的package中还是放在需要它的Widget旁边,都不会丢失它的可测试性。


// A shared state that can be accessed by multiple widgets at the same time.

class Count extends _$Count {

int build() => 0;

void increment() => state++;
}

// Consumes the shared state and rebuild when it changes
class Title extends ConsumerWidget {

Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countProvider);
return Text('$count');
}
}

最小粒度更新UI和重新计算状态

我们无需在 build 中对列表进行排序或过滤,也不必依赖高级的缓存机制。

使用 Provider"families" 修饰符,那么它只会在你真正需要的时候才发起HTTP请求或整理你的列表。



List<Todo> filteredTodos(FilteredTodosRef ref) {
// Providers can consumer other providers using the "ref" object.
// With ref.watch, providers will automatically update if the watched values changes.
final List<Todo> todos = ref.watch(todosProvider);
final Filter filter = ref.watch(filterProvider);

switch (filter) {
case Filter.all:
return todos;
case Filter.completed:
return todos.where((todo) => todo.completed).toList();
case Filter.uncompleted:
return todos.where((todo) => !todo.completed).toList();
}
}

Simplify day-to-day work with refactors

Riverpod offers various refactors, such as "Wrap widget in a Consumer" and many more. See the list of refactorings.

Simplify day-to-day work with refactors

Keep your code maintainable with lint rules

New lint-rules specific to Riverpod are implemented and more are continuously added. This ensures your code stays in the best conditions. See the list of lint rules.

Keep your code maintainable with lint rules

安全使用Provider

使用provider不再导致错误的状态。恰当地使用provider,你可以始终获得一个可靠的结果。

这在异步操作中也是如此,Riverpod可以让你简洁地处理loading/error状态。



Future<Configuration> configurations(ConfigurationsRef ref) async {
final uri = Uri.parse('configs.json');
final rawJson = await File.fromUri(uri).readAsString();

return Configuration.fromJson(json.decode(rawJson));
}

class Example extends ConsumerWidget {

Widget build(BuildContext context, WidgetRef ref) {
final configs = ref.watch(configurationsProvider);

// Use pattern matching to safely handle loading/error states
return switch (configs) {
AsyncData(:final value) => Text('data: ${value.host}'),
AsyncError(:final error) => Text('error: $error'),
_ => const CircularProgressIndicator(),
};
}
}

在DevTools中检查状态

你可以在Flutter的开发工具中一目了然地看到Riverpod的各种状态。
此外,一款功能更全面的状态检查工具正在开发中。

在DevTools中检查状态