Flutter日志记录与Redux调试插件redux_logging的使用
Flutter日志记录与Redux调试插件redux_logging的使用
redux_logging
redux_logging
连接了一个Logger到一个Redux Store。它也可以简单地打印最新的状态和动作变化。
默认情况下,这个类不会在你的控制台或终端上打印任何内容,也不会将数据发送到类似Fabric或Sentry这样的Web服务。它只是将条目记录到一个Logger
实例中。
如果你想简单地将最新的动作和状态打印到你的控制台或终端,可以创建一个new LoggingMiddleware.printer()
并将其传递给Store创建时。
如果你希望对日志数据的发送位置有更多的控制权,你可以监听你的Logger的onRecord
Stream。
Dart 版本
- Dart 1 支持: 0.1.x
- Dart 2 支持: 0.2.x+
简单打印示例
如果你想要一种简单的方法来打印分发的动作到你的控制台/终端,可以使用new LoggingMiddleware.printer()
工厂方法。
注意: LoggingMiddleware
需要是中间件列表中的最后一个。
import "package:redux/redux.dart";
import 'package:redux_logging/redux_logging.dart';
final store = new Store<int>(
(int state, dynamic action) => state + 1,
initialValue: 0,
// 注意LoggingMiddleware应该放在中间件列表的最后!
middleware: [myOtherMiddleware, new LoggingMiddleware.printer()]
);
store.dispatch("Hi"); // 打印 {Action: "Hi", Store: 1, Timestamp: ...}
示例
如果你只想将动作记录到一个Logger
,并且选择如何处理输出,可以使用默认构造函数。
import 'package:logging/logging.dart';
import "package:redux/redux.dart";
import 'package:redux_logging/redux_logging.dart';
// 创建你自己的Logger
final logger = new Logger("Redux Logger");
// 将其传递给你的中间件
final middleware = new LoggingMiddleware(logger: logger);
final store = new Store<int>(
(int state, dynamic action) => state + 1,
initialState: 0,
middleware: [middleware],
);
// 注意:监听一个logger实例的一个特点是,实际上你是在监听*所有*logger的单例实例。
logger.onRecord
// 过滤出发送到你的logger实例的[LogRecord]
.where((record) => record.loggerName == logger.name)
// 打印它们(或者做一些更有趣的事情!)
.listen((loggingMiddlewareRecord) => print(loggingMiddlewareRecord));
格式化日志消息
这个库自带两个格式化程序:
LoggingMiddleware.singleLineFormatter
LoggingMiddleware.multiLineFormatter
你可以通过实现自己的MessageFormatter
并将其传递给LoggingMiddleware
构造函数来可选地控制将要记录的消息的格式。它是一个简单的函数,接受三个参数:State、Action和Timestamp。
格式化示例
import "package:redux/redux.dart";
import 'package:redux_logging/redux_logging.dart';
// 创建一个只打印分发动作的格式化器
String onlyLogActionFormatter<State>(
State state,
dynamic action,
DateTime timestamp,
) {
return "{Action: $action}";
}
// 使用格式化器创建你的中间件。
final middleware = new LoggingMiddleware(formatter: onlyLogActionFormatter);
// 将带有格式化器的中间件添加到你的Store
final store = new Store<int>(
(int state, dynamic action) => state + 1,
initialState: 0,
middleware: [middleware],
);
完整示例Demo
为了提供一个完整的演示,以下是一个整合了上述所有概念的完整Flutter应用示例。
import 'package:flutter/material.dart';
import 'package:redux/redux.dart';
import 'package:redux_logging/redux_logging.dart';
import 'package:logging/logging.dart';
void main() {
// 创建你自己的Logger
final logger = Logger('Redux Logger');
// 创建一个格式化器,以便自定义日志输出
String customFormatter<State>(State state, dynamic action, DateTime timestamp) {
return "Custom Log - Action: $action, State: $state, Timestamp: $timestamp";
}
// 创建中间件
final middleware = LoggingMiddleware(
logger: logger,
formatter: customFormatter,
);
// 创建Store
final store = Store<int>(
(int state, dynamic action) => state + 1,
initialState: 0,
middleware: [middleware],
);
// 监听日志记录
logger.onRecord.listen((record) {
if (record.loggerName == logger.name) {
print(record.message);
}
});
runApp(MyApp(store: store));
}
class MyApp extends StatelessWidget {
final Store<int> store;
MyApp({required this.store});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Redux Logging Demo',
home: Scaffold(
appBar: AppBar(title: Text('Redux Logging Demo')),
body: ReduxLoggingDemo(store: store),
),
);
}
}
class ReduxLoggingDemo extends StatefulWidget {
final Store<int> store;
ReduxLoggingDemo({required this.store});
@override
_ReduxLoggingDemoState createState() => _ReduxLoggingDemoState();
}
class _ReduxLoggingDemoState extends State<ReduxLoggingDemo> {
@override
void initState() {
super.initState();
widget.store.dispatch("Initial Dispatch");
}
void _incrementCounter() {
widget.store.dispatch("Increment Counter");
}
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${widget.store.state}',
style: Theme.of(context).textTheme.headline4,
),
ElevatedButton(
onPressed: _incrementCounter,
child: Text('Increment'),
),
],
),
);
}
}
在这个完整的示例中,我们创建了一个简单的Flutter应用程序,它使用Redux管理状态,并通过redux_logging
插件记录每个动作和状态的变化。每当点击“Increment”按钮时,都会触发一个动作,该动作会增加状态值,并且日志会被打印出来。
更多关于Flutter日志记录与Redux调试插件redux_logging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter日志记录与Redux调试插件redux_logging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是如何在Flutter项目中使用日志记录和Redux调试插件redux_logging
的详细代码示例。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加redux_logging
和logging
依赖:
dependencies:
flutter:
sdk: flutter
redux: ^5.0.0 # 确保你使用的redux版本与redux_logging兼容
redux_logging: ^0.4.0 # 检查最新版本
logging: ^1.0.0
然后运行flutter pub get
来安装这些依赖。
2. 配置日志记录
在你的Flutter项目的入口文件(通常是main.dart
)中配置日志记录:
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:redux/redux.dart';
import 'package:redux_logging/redux_logging.dart';
// 配置日志记录器
final Logger logger = Logger('MyApp');
void configureLogging() {
hierarchicalLoggingEnabled = true;
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((LogRecord rec) {
print('${rec.level.name}: ${rec.time}: ${rec.message}');
if (rec.error != null && rec.stackTrace != null) {
print(rec.error);
print(rec.stackTrace);
}
});
}
void main() {
configureLogging();
runApp(MyApp());
}
3. 创建Redux Store并添加Logger Middleware
接下来,在你的Redux store配置中添加redux_logging
的logger middleware:
import 'package:redux/redux.dart';
import 'package:redux_logging/redux_logging.dart';
// 示例Action和State
enum AppAction { increment, decrement }
class AppState {
final int counter;
AppState({required this.counter});
AppState copyWith({int? counter}) {
return AppState(counter: counter ?? this.counter);
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AppState &&
runtimeType == other.runtimeType &&
counter == other.counter;
@override
int get hashCode => counter.hashCode;
}
AppState appReducer(AppState state, dynamic action) {
if (action == AppAction.increment) {
return state.copyWith(counter: state.counter + 1);
} else if (action == AppAction.decrement) {
return state.copyWith(counter: state.counter - 1);
}
return state;
}
void main() {
configureLogging();
final store = Store<AppState>(
appReducer,
initialState: AppState(counter: 0),
middleware: [createLoggingMiddleware<AppState>()],
);
runApp(MyApp(store: store));
}
4. 使用Store和UI组件
最后,在你的Flutter应用中使用Redux store来管理状态,并展示UI组件:
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';
class MyApp extends StatelessWidget {
final Store<AppState> store;
MyApp({required this.store});
@override
Widget build(BuildContext context) {
return StoreProvider<AppState>(
store: store,
child: MaterialApp(
home: CounterScreen(),
),
);
}
}
class CounterScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Redux Logging Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StoreConnector<AppState, int>(
converter: (store) => store.state.counter,
builder: (context, counter) {
return Text(
'$counter',
style: Theme.of(context).textTheme.headline4,
);
},
),
],
),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
onPressed: () {
StoreProvider.of<AppState>(context).dispatch(AppAction.increment);
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
SizedBox(height: 10),
FloatingActionButton(
onPressed: () {
StoreProvider.of<AppState>(context).dispatch(AppAction.decrement);
},
tooltip: 'Decrement',
child: Icon(Icons.remove),
),
],
),
);
}
}
总结
以上代码展示了如何在Flutter项目中配置日志记录和使用redux_logging
插件来调试Redux状态管理。通过配置日志记录器和在Redux store中添加logger middleware,你可以在控制台中看到Redux action和state的变化,帮助你更好地调试应用。