Flutter副作用管理插件side_effect_bloc的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter副作用管理插件side_effect_bloc的使用

Pub

side_effect_bloc 是一个扩展了 bloc 的插件,它提供了一个单独的流来处理那些应该只被消费一次的事件。这使得你可以将与导航、Toast/Snackbar 消息等相关的事件从 bloc 的状态中分离出来。

使用方法

声明 Bloc

添加 Mixin 到现有的 Bloc

class FeatureBloc extends Bloc<FeatureEvent, FeatureState>
    with SideEffectBlocMixin<FeatureEvent, FeatureState, FeatureSideEffect> {
  FeatureBloc() : super(FeatureState.initial());
}

继承自 Bloc

class FeatureBloc extends SideEffectBloc<FeatureEvent, FeatureState, FeatureSideEffect> {
  FeatureBloc() : super(FeatureState.initial());
}

发射副作用

class FeatureBloc extends SideEffectBloc<FeatureEvent, FeatureState, FeatureSideEffect> {
  FeatureBloc() : super(FeatureState.initial()) {
    on<ItemClick>(
      (event, emit) {
        produceSideEffect(FeatureSideEffect.openItem(event.id));
      },
    );
  }
}

监听副作用

// feature_view.dart
BlocSideEffectListener<FeatureBloc, FeatureSideEffect>(
  listener: (BuildContext context, FeatureSideEffect sideEffect) {
    sideEffect.when(
      goToNext: () => Navigator.of(context).pushNamed("/sub"),
      openSnackbar: () {
        const snackBar = SnackBar(
          content: Text('Yay! A SnackBar!'),
        );
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      },
    );
  },
  child: ...,
)

示例代码

以下是一个完整的示例代码,展示了如何在 Flutter 应用中使用 side_effect_bloc

main.dart

import 'package:flutter/material.dart';
import 'package:side_effect_bloc/side_effect_bloc.dart';
import 'feature_bloc.dart';
import 'feature_view.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Side Effect Bloc Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: FeatureView(),
    );
  }
}

feature_bloc.dart

import 'package:bloc/bloc.dart';
import 'package:side_effect_bloc/side_effect_bloc.dart';
import 'feature_event.dart';
import 'feature_state.dart';
import 'feature_side_effect.dart';

class FeatureBloc extends SideEffectBloc<FeatureEvent, FeatureState, FeatureSideEffect> {
  FeatureBloc() : super(FeatureState.initial()) {
    on<ItemClick>(
      (event, emit) {
        produceSideEffect(FeatureSideEffect.openItem(event.id));
      },
    );
  }
}

feature_event.dart

part of 'feature_bloc.dart';

abstract class FeatureEvent {}

class ItemClick extends FeatureEvent {
  final int id;

  ItemClick(this.id);
}

feature_state.dart

part of 'feature_bloc.dart';

class FeatureState {
  static FeatureState initial() {
    return FeatureState();
  }

  // Add your state properties here
}

feature_side_effect.dart

part of 'feature_bloc.dart';

abstract class FeatureSideEffect {}

class OpenItem extends FeatureSideEffect {
  final int id;

  OpenItem(this.id);
}

class GoToNext extends FeatureSideEffect {}

class OpenSnackbar extends FeatureSideEffect {}

feature_view.dart

import 'package:flutter/material.dart';
import 'package:side_effect_bloc/side_effect_bloc.dart';
import 'feature_bloc.dart';
import 'feature_event.dart';

class FeatureView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => FeatureBloc(),
      child: Scaffold(
        appBar: AppBar(
          title: Text('Side Effect Bloc Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              context.read<FeatureBloc>().add(ItemClick(1));
            },
            child: Text('Click Me'),
          ),
        ),
      ),
    );
  }
}

feature_side_effect_listener.dart

import 'package:flutter/material.dart';
import 'package:side_effect_bloc/side_effect_bloc.dart';
import 'feature_bloc.dart';
import 'feature_side_effect.dart';

class FeatureSideEffectListener extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocSideEffectListener<FeatureBloc, FeatureSideEffect>(
      listener: (BuildContext context, FeatureSideEffect sideEffect) {
        sideEffect.when(
          openItem: (id) => Navigator.of(context).pushNamed("/sub"),
          goToNext: () => Navigator.of(context).pushNamed("/next"),
          openSnackbar: () {
            const snackBar = SnackBar(
              content: Text('Yay! A SnackBar!'),
            );
            ScaffoldMessenger.of(context).showSnackBar(snackBar);
          },
        );
      },
      child: FeatureView(),
    );
  }
}

通过以上示例代码,你可以看到如何在 Flutter 应用中使用 side_effect_bloc 来管理副作用。希望这些示例对你有所帮助!


更多关于Flutter副作用管理插件side_effect_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter副作用管理插件side_effect_bloc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用side_effect_bloc插件来管理副作用的一个简单示例。side_effect_bloc是一个用于处理BLoC(Business Logic Component)架构中副作用(如网络请求、计时器等)的插件。

首先,确保你已经在pubspec.yaml文件中添加了side_effect_bloc的依赖:

dependencies:
  flutter:
    sdk: flutter
  side_effect_bloc: ^latest_version  # 替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,我们将创建一个简单的Flutter应用,演示如何使用side_effect_bloc来处理副作用。

1. 创建BLoC

首先,创建一个BLoC来处理状态管理和副作用。

import 'package:bloc/bloc.dart';
import 'package:side_effect_bloc/side_effect_bloc.dart';

enum CounterEvent { increment, decrement }

class CounterState {
  final int count;

  CounterState(this.count);

  @override
  String toString() => 'CounterState(count: $count)';
}

class CounterBloc extends Bloc<CounterEvent, CounterState> with SideEffectBloc {
  CounterBloc() : super(CounterState(0)) {
    on<CounterEvent>((event, emit) async {
      if (event == CounterEvent.increment) {
        emit(CounterState(state.count + 1));
      } else if (event == CounterEvent.decrement) {
        emit(CounterState(state.count - 1));
      }
      
      // 添加副作用
      addSideEffect(effect: _handleSideEffect);
    });
  }

  Future<void> _handleSideEffect() async {
    // 模拟副作用,比如网络请求或计时器
    await Future.delayed(Duration(seconds: 1));
    print('Side effect handled: ${state.count}');
  }
}

2. 创建UI

接下来,创建一个简单的UI来与BLoC进行交互。

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_bloc.dart';  // 引入你创建的BLoC文件

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Counter App')),
        body: Center(
          child: BlocProvider(
            create: (context) => CounterBloc(),
            child: CounterPage(),
          ),
        ),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        BlocBuilder<CounterBloc, CounterState>(
          builder: (context, state) {
            return Text('${state.count}');
          },
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () => context.read<CounterBloc>().add(CounterEvent.increment),
          child: Text('Increment'),
        ),
        SizedBox(height: 10),
        ElevatedButton(
          onPressed: () => context.read<CounterBloc>().add(CounterEvent.decrement),
          child: Text('Decrement'),
        ),
      ],
    );
  }
}

3. 运行应用

现在,你可以运行你的Flutter应用。当你点击“Increment”或“Decrement”按钮时,BLoC将更新状态,并且副作用(在这个例子中是延迟1秒后打印当前计数)将被处理。

这个示例展示了如何使用side_effect_bloc插件来管理Flutter应用中的副作用。你可以根据自己的需求扩展这个示例,比如添加实际的网络请求或处理更复杂的副作用逻辑。

回到顶部