跳到主要内容
声明式编程

声明式编程

以类似于无状态小部件的方式编写业务逻辑。
让您的网络请求在必要时自动重新计算,并使您的逻辑易于重用、组合、维护。

轻松实现常见的 UI 模式

轻松实现常见的 UI 模式

使用 Riverpod,只需几行代码即可实现常见但复杂的 UI 模式,例如“下拉刷新”、“实时搜索”等。

工具准备就绪

工具准备就绪

Riverpod 通过将常见错误作为编译错误来增强编译器。 它还提供自定义 lint 规则和重构选项。 它甚至有一个用于生成文档的命令行。

特性

  • 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 consume 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();
}
}

通过重构简化日常工作

Riverpod 提供了多种重构提示, 例如 "Wrap widget in a Consumer" 等等。 请参阅 重构提示列表.

通过重构简化日常工作

使用 lint 规则保持代码可维护

实现了 Riverpod 定制的 lint 新规则,并且还会不断添加更多规则。这可确保您的代码保持最佳状态。请参阅 lint 规则列表

使用 lint 规则保持代码可维护

安全的读取 providers

读取 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 中检查你的状态

使用了 Riverpod,你的状态将可以在 Flutter 自带的 DevTools 中一目了然。

此外,一款全面的状态检查工具正在开发中……

在 DevTools 中检查你的状态