Flutter异步状态管理插件async_cubits的使用

Flutter 异步状态管理插件 async_cubits 的使用

async_cubits

style: very_good_analysis License: MIT

一个用于简化并一致地处理异步操作的插件包。

启发灵感

该插件包受到 Riverpod 的 FutureProviderStreamProvider 的启发。AsyncValue 类与 riverpod 包中的类相似。请参阅 riverpod 包中的优秀工作。

安装 💻

要开始使用 Async Cubits,必须在您的机器上安装 Flutter SDK。

flutter pub add async_cubits

使用 🚀

导入包

import 'package:async_cubits/async_cubits.dart';

使用 FutureCubit

FutureCubits 是一种可以用于执行返回值的异步操作的 Cubit。例如,从 API 获取数据。

class GetUserCubit extends FutureCubit<User> {
  final UserRepository _userRepository;

  GetUserCubit(this._userRepository);

  @override
  Future<User> future() => _userRepository.getUser();
}
加载异步数据

要触发异步数据获取,使用 load() 方法。

当调用 load() 时,Cubit 将按以下顺序发出 AsyncValue<T>

  • AsyncValue.loading()
  • 如果操作成功且数据可用,则 AsyncValue.data(fetchedData)
  • 如果操作失败,则 AsyncValue.error(error, stackTrace)

在您的 UI 中,您可以使用 BlocProviderBlocBuilder 来加载和访问数据。

BlocProvider(
  create: (context) => GetUserCubit(
    context.read<UserRepository>(),
  )..load(), // 当创建 Cubit 时加载数据
  child: BlocBuilder<GetUserCubit, AsyncState<User>>(
    builder: (context, state) {
      return state.when(
        loading: () => CircularProgressIndicator(),
        error: (error) => Text(error),
        data: (user) => Text(user.name),
      );
    },
  ),
);
触发刷新

如果要触发数据的刷新,可以在 Cubit 上调用 refresh 方法。

ElevatedButton(
  onPressed: () => context.read<GetUserCubit>().refresh(),
  child: Text('Refresh'),
),

当调用 refresh() 时,Cubit 将按以下顺序发出 AsyncValue<T>

  • isLoadingtrue 并且 value 包含之前加载的值,这有助于显示之前加载的内容,然后立即切换到新值而不会显示加载指示器。如果您想显示加载指示器,可以在使用 AsyncValue.when 时将 skipLoadingOnRefresh 设置为 false
  • 如果操作成功并且有新值可用,则状态的 isLoading 变为 false 并且 value 包含新值
  • 如果操作失败,则状态的 isLoading 变为 falseerrorstackTrace 不为空,并且 value 包含之前加载的值。这种行为允许显示之前加载的内容,并带有刷新错误消息(要实现这一点,可以使用 AsyncValue.when 方法中的 skipError

因此,根据上述示例,如果数据成功获取,将渲染 Text(user.name) 并且在 Cubit 刷新时不会显示加载指示器。

使用新参数加载/刷新数据

要使用传递给 future 方法的新参数来加载/刷新数据,使用 FutureWithArgsCubit。此 Cubit 的行为类似于 FutureCubit

class GetUserByIdCubit extends FutureWithArgsCubit<int, User> {
  final UserRepository _userRepository;

  GetUserCubit(this._userRepository);

  @override
  Future<User> future(int id) => _userRepository.getUserById(id);
}

然后使用参数调用 loadrefresh

context.read<GetUserByIdCubit>().load(1);

context.read<GetUserByIdCubit>().refresh(1);

使用 StreamCubit

StreamCubits 是一种可以用于监听异步事件流的 Cubit。例如,监听来自 WebSocket 的数据流。

class NewMessageCubit extends StreamCubit<Message> {
  final MessageRepository _messageRepository;

  NewMessageCubit(this._messageRepository);

  @override
  Stream<Message> dataStream() => _messageRepository.newMessageStream();
}

StreamCubit 发出 AsyncValue<T>,因此监听状态变化与 FutureCubit 类似。

class NewMessageWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final cubit = context.watch<NewMessageCubit>();
    final state = cubit.state;

    return state.when(
      loading: LoadingWidget.new,
      error: (error, stackTrace) => ErrorWidget(error),
      data: (data) => LoadedMessage(data),
    );
  }
}

使用 MutationCubit

MutationCubit 是一种专门设计用于处理异步突变的 Cubit。它促进了异步任务的执行,并在整个过程中管理各种状态,包括加载、成功和失败。通常用于突变后端、本地数据库等的状态。

示例:

class MyMutationCubit extends MutationCubit<String, int> {
  @override
  Future<int> mutation(String input) async {
    // 在这里执行异步突变逻辑
    // 例如,发起 API 调用、更新数据库等。
    return 42; // 用实际结果替换
  }
}

要调用突变,使用 invoke 方法:

cubit.invoke('input');

更多关于Flutter异步状态管理插件async_cubits的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


当然,下面是一个关于如何在Flutter应用中使用async_cubits插件进行异步状态管理的代码示例。async_cubits是一个简化和增强异步状态管理的库,它基于cubitbloc架构。

首先,确保在你的pubspec.yaml文件中添加async_cubits依赖:

dependencies:
  flutter:
    sdk: flutter
  async_cubits: ^最新版本号

然后运行flutter pub get来获取依赖。

接下来,我们创建一个简单的示例,展示如何使用AsyncCubit来管理异步数据。

1. 创建AsyncCubit

首先,创建一个AsyncCubit类来处理数据获取逻辑。例如,我们创建一个用于获取用户数据的UserCubit

import 'package:async_cubits/async_cubits.dart';
import 'package:flutter/material.dart';

class UserState {
  final bool isLoading;
  final String? user;
  final String? error;

  UserState({
    required this.isLoading,
    this.user,
    this.error,
  });

  UserState copyWith({
    bool? isLoading,
    String? user,
    String? error,
  }) {
    return UserState(
      isLoading: isLoading ?? this.isLoading,
      user: user ?? this.user,
      error: error ?? this.error,
    );
  }
}

class UserCubit extends AsyncCubit<UserState> {
  UserCubit() : super(UserState(isLoading: false));

  Future<void> fetchUser() async {
    emit(state.copyWith(isLoading: true));
    try {
      // 模拟一个异步操作,例如从API获取用户数据
      await Future.delayed(const Duration(seconds: 2));
      final String user = 'John Doe';
      emit(state.copyWith(isLoading: false, user: user));
    } catch (e) {
      emit(state.copyWith(isLoading: false, error: e.toString()));
    }
  }
}

2. 使用UserCubit在UI中

然后,在你的Flutter应用中使用这个UserCubit来管理UI状态。

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:async_cubits_example/cubits/user_cubit.dart'; // 假设文件路径为cubits/user_cubit.dart

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Async Cubits Example')),
        body: BlocProvider(
          create: (_) => UserCubit(),
          child: UserScreen(),
        ),
      ),
    );
  }
}

class UserScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocConsumer<UserCubit, UserState>(
      listener: (context, state) {
        // 这里可以处理一些需要响应状态变化的逻辑,比如显示SnackBar
      },
      builder: (context, state) {
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              if (state.isLoading)
                CircularProgressIndicator(),
              if (state.error != null)
                Text('Error: ${state.error!}'),
              if (state.user != null)
                Text('User: ${state.user!}'),
              ElevatedButton(
                onPressed: () => context.read<UserCubit>().fetchUser(),
                child: Text('Fetch User'),
              ),
            ],
          ),
        );
      },
    );
  }
}

3. 运行应用

运行你的Flutter应用,你应该会看到一个简单的界面,点击“Fetch User”按钮后,会显示一个加载指示器,然后显示获取到的用户数据或者错误信息。

这个示例展示了如何使用async_cubits进行异步状态管理。通过AsyncCubit,你可以轻松地管理UI的异步状态,同时保持代码的清晰和可维护性。

回到顶部