Flutter状态管理插件reactive_state_machine的使用
Flutter状态管理插件reactive_state_machine的使用
reactive_state_machine
提供了一种灵活且用户友好的方法来创建反应式层次化的有限状态机。它是用纯 Dart 编写的。
注意:此包尚未达到生产就绪状态。未来版本可能会更改 API。
该包引入了两种类型的 StateMachines。它们都是层次化的有限状态机,但定义和使用状态和转换的方式不同。两者都实现了 StateMachineBase
接口。
-
EventStateMachine
是一种从事件总线接收输入的状态机。事件基于当前状态进行处理,并可能触发副作用或状态转换。它在状态机应响应流时或需要同时管理多个事件源时工作最佳。 -
CommandStateMachine
是一种通过调用状态的方法进行交互的状态机。这种机器设计用于利用 Dart 的模式匹配功能,通过显式定义允许的转换来实现编译时安全的交互。它在消费者希望以命令方式与状态机交互时工作最佳。
转换和事件处理依赖于 State
和 Event
类型,而不是对象相等性。
状态机不强制特定的反应式 API,给开发者选择实现(如 Stream
、ChangeNotifier
、BehaviorSubject
等)的灵活性。
该包包括两种机器类型基于 Dart Stream
的实现:StreamEventStateMachine
和 StreamCommandStateMachine
。
flutter_reactive_state_machine
包为 Flutter 的标准 Listenable
提供了额外的实现,并提供了其他专门为 Flutter 定制的工具。
EventStateMachine
sealed class State {
const State();
}
class Green extends State {
const Green();
}
class Red extends State {
const Red();
}
class Orange extends State {
const Orange();
}
sealed class Event {
const Event();
}
class TimerFinished extends Event {
const TimerFinished();
}
final class TraficLight extends StreamEventStateMachine<State, Event> {
TraficLight(super.initial);
@override
late final states = {
// Green state
define<Green> (($) => $
..onEnter(_startTimer)
..on<TimerFinished>((state, event) => const Orange())),
// Orange state
define<Orange> (($) => $
..onEnter(_startTimer)
..on<TimerFinished>((state, event) => const Red())),
// Red state
define<Red> (($) => $
..onEnter(_startTimer)
..on<TimerFinished>((state, event) => const Green())),
};
void _startTimer(_) {
Timer(Duration(seconds: 1), () => add(const TimerFinished()));
}
}
CommandStateMachine
sealed class UserState with State<UserModel, UserState> {}
class Unknown extends UserState {
@override
Future<void> onEnter() async {
final user = await machine.authenticationService.currentUser();
if (user != null) {
transitionTo(Authenticated(user));
} else {
transitionTo(Unauthenticated());
}
}
}
class Unauthenticated extends UserState {
Future<bool> login() async {
final user = await machine.authenticationService.tryLogin();
if (user != null) {
transitionTo(Authenticated(user));
return true;
} else {
return false;
}
}
}
class Authenticated extends UserState {
Authenticated(this.user);
final User user;
Future<void> logout() async {
await machine.authenticationService.logout();
transitionTo(Unauthenticated());
}
}
final class UserModel extends StreamCommandStateMachine<UserState> {
UserModel({
required this.authenticationService,
}) : super(Unknown());
final AuthenticationService authenticationService;
}
使用示例
void main() async {
final machine = MyStateMachine();
if (machine.state case SomeState state) {
state.yourData;
}
machine.ifState((TestState state) => state.doSomething());
final content = switch (machine.state) {
StateA() || StateB() => "A or B",
StateC() => "C",
};
}
更多关于Flutter状态管理插件reactive_state_machine的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter状态管理插件reactive_state_machine的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
reactive_state_machine
是一个轻量级的 Flutter 状态管理插件,它基于状态机的概念,允许开发者通过定义状态和事件来管理应用的状态。它非常适合用于复杂的 UI 交互和状态转换场景。
安装
首先,你需要在 pubspec.yaml
文件中添加 reactive_state_machine
依赖:
dependencies:
flutter:
sdk: flutter
reactive_state_machine: ^0.1.0
然后运行 flutter pub get
来安装依赖。
基本概念
- State(状态): 应用在某一时刻的状态。每个状态可以包含一些数据。
- Event(事件): 触发状态转换的动作。事件可以携带数据。
- State Machine(状态机): 管理状态和状态转换的逻辑。
使用步骤
1. 定义状态和事件
首先,你需要定义应用的状态和事件。这些通常是枚举类型。
enum MyState { initial, loading, loaded, error }
enum MyEvent { fetchData, dataFetched, errorOccurred }
2. 创建状态机
接下来,创建一个状态机并定义状态转换逻辑。
import 'package:reactive_state_machine/reactive_state_machine.dart';
final stateMachine = StateMachine<MyState, MyEvent>(
initialState: MyState.initial,
transitions: {
MyState.initial: {
MyEvent.fetchData: MyState.loading,
},
MyState.loading: {
MyEvent.dataFetched: MyState.loaded,
MyEvent.errorOccurred: MyState.error,
},
MyState.loaded: {
MyEvent.fetchData: MyState.loading,
},
MyState.error: {
MyEvent.fetchData: MyState.loading,
},
},
);
3. 监听状态变化
你可以通过 stateMachine.stateStream
来监听状态的变化。
stateMachine.stateStream.listen((state) {
print('Current state: $state');
});
4. 触发事件
通过 stateMachine.trigger
方法来触发事件,从而驱动状态转换。
stateMachine.trigger(MyEvent.fetchData);
5. 在 Flutter 中使用
你可以在 Flutter 的 StatefulWidget
中使用 StateMachine
来管理状态。
import 'package:flutter/material.dart';
import 'package:reactive_state_machine/reactive_state_machine.dart';
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final stateMachine = StateMachine<MyState, MyEvent>(
initialState: MyState.initial,
transitions: {
MyState.initial: {
MyEvent.fetchData: MyState.loading,
},
MyState.loading: {
MyEvent.dataFetched: MyState.loaded,
MyEvent.errorOccurred: MyState.error,
},
MyState.loaded: {
MyEvent.fetchData: MyState.loading,
},
MyState.error: {
MyEvent.fetchData: MyState.loading,
},
},
);
[@override](/user/override)
void initState() {
super.initState();
stateMachine.stateStream.listen((state) {
setState(() {});
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Reactive State Machine Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (stateMachine.currentState == MyState.initial)
Text('Initial State'),
if (stateMachine.currentState == MyState.loading)
CircularProgressIndicator(),
if (stateMachine.currentState == MyState.loaded)
Text('Data Loaded!'),
if (stateMachine.currentState == MyState.error)
Text('Error Occurred!'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
stateMachine.trigger(MyEvent.fetchData);
},
child: Text('Fetch Data'),
),
],
),
),
);
}
}
void main() => runApp(MaterialApp(home: MyApp()));