Flutter轻量级的状态管理库flutter_nano_var的使用
Flutter轻量级的状态管理库flutter_nano_var的使用
介绍
flutter_nano_var
是一个轻量级的状态管理库,独立于任何依赖注入方法。它可以帮助开发者在Flutter应用中轻松管理状态,同时减少样板代码的编写。以下是关于如何使用 flutter_nano_var
的详细说明和完整示例。
基本用法
-
创建 NanoVar 实例
首先,创建一个
NanoVar
实例并为其指定初始值。例如,创建一个计数器:final counter = NanoVar(0);
-
存储 NanoVar 实例
为了确保在 widget 树重建时不会丢失
NanoVar
实例的引用,需要将其存储在State
中。例如,在StatefulWidget
的State
类中声明NanoVar
实例:class _MyHomePageState extends State<MyHomePage> { final _counter = NanoVar(0); // ... }
-
使用 NanoObs 监听变化
使用
NanoObs
小部件来监听NanoVar
实例的变化,并在值发生变化时自动重建小部件。例如,显示计数器的值:NanoObs( builder: (context, watch) => Text( '${watch(_counter)}', style: Theme.of(context).textTheme.headline4, ), )
-
更新 NanoVar 实例的值
可以通过直接赋值或调用
value
属性来更新NanoVar
实例的值。例如,增加计数器的值:void _incrementCounter() { _counter.value++; }
注意:不能在构建小部件时更新
NanoVar
实例的值,但可以在按钮回调等其他地方进行更新。
读取只读实例
可以通过将 NanoVar
实例转换为 NanoRead
实例来限制其为只读。例如:
final NanoRead<int> readOnlyCounter = counter;
// 这行代码会导致编译错误
readOnlyCounter.value = 1;
功能特性
NanoVar
实例支持函数式编程的功能,如 Functor
、Applicative Functor
和 Monad
。
-
Functor
使用
map
方法可以将NanoVar
实例中的值转换为另一个值。例如,将整数计数器转换为字符串:final stringCounter = counter.map((int value) { return value.toString(); });
然后可以在小部件中使用
stringCounter
:NanoObs( builder: (context, watch) => Text(watch(stringCounter)), )
-
Applicative Functor
使用
liftA2
方法可以结合两个NanoVar
实例的值,并将其转换为第三个值。例如,结合整数计数器和浮点数计数器:final doubleCounter = NanoVar(0.0); final stringCounter = counter.liftA2((int firstValue, double secondValue) { return (firstValue + secondValue).toString(); }, doubleCounter);
当
counter
或doubleCounter
发生变化时,stringCounter
会自动更新。 -
Monad
使用
bind
方法可以将NanoVar
实例中的值转换为另一个NanoVar
实例。例如,将整数计数器转换为字符串计数器:final stringCounter = counter.bind((int value) { return NanoVar(value.toString()); });
当
counter
或最近返回的NanoVar
实例发生变化时,stringCounter
会自动更新。
异步 Future 观察
flutter_nano_var
还支持异步 Future
的观察。例如,假设有一个异步函数 loadDetails
:
Future<DetailsModel> loadDetails(int id) async {
return await callEndpoint("/details/$id");
}
可以使用 nanoRead
方法将 Future
转换为 NanoRead
实例,并在小部件中监听其状态:
final futureNanoRead = loadDetails(1).nanoRead;
void getStatus(status) {
return status.status(
uncompleted: () {
return "futureNanoRead has not yet completed";
},
success: (value) {
return "futureNanoRead has completed with the value $value";
},
fail: (error, stackTrace) {
return "futureNanoRead has completed with the error $error and the stack trace $stackTrace";
},
);
}
final widget = NanoObs(
builder: (context, watch) => Text(getStatus(watch(futureNanoRead))),
);
还可以结合 bind
方法,在每次 counter
发生变化时调用 loadDetails
,并管理最新的加载状态:
final detailsStatus = counter.bind((int value) {
return loadDetails(value).nanoRead;
});
完整示例 Demo
以下是一个完整的示例,展示了如何使用 flutter_nano_var
来管理状态并构建一个简单的计数器应用:
import 'package:flutter/material.dart';
import 'package:flutter_nano_var/flutter_nano_var.dart';
import 'package:nano_var/nano_var.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
final String title;
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
/// A [NanoVar] instance for the counter.
///
/// Notice that this variable is declared in a [State] instance, which means
/// the reference to the instance is kept even if the widget tree is rebuilt.
final _counter = NanoVar(0);
void _incrementCounter() {
// Increment the counter's value directly.
// It's not required to explicitly call setState in relation to this
// change.
_counter.value++;
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
// Use a NanoObs to track changes of _counter by calling watch.
NanoObs(
builder: (context, watch) => Text(
'${watch(_counter)}',
style: Theme.of(context).textTheme.headline4,
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
更多关于Flutter轻量级的状态管理库flutter_nano_var的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html