Flutter状态管理插件built_redux的使用

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

Flutter状态管理插件built_redux的使用

什么是built_redux

built_redux 是一个用Dart编写的库,它强制遵循不可变性。built_redux 不仅是 redux 的的一个实现,而且是一个框架,用于以类型安全的方式构建中间件和 reducer。

使用示例

下面是一个简单的的 counter app 示例,展示了如何使用 built_redux 进行状态管理。

import 'package:built_value/built_value.dart';
import 'package:built_redux/built_redux.dart';

part 'example.g.dart';

void main() {
  // 创建一个 Redux 存储器,持有应用程序的状态。
  // 其 API 包含三个获取器:stream、state 和 actions。
  final store = Store<Counter, CounterBuilder, CounterActions>(
    reducerBuilder.build(), // build 返回一个 reducer 函数
    Counter(),
    CounterActions(),
  );

  print(store.state.count); // 0
  store.actions.increment(1: 1);
  print(store.state.count); // 1
  store.actions.increment(2);
  print(store.state.count); // 3
  store.actions.decrement(1: 1);
  print(store.state.count); // 2
}

// 这是一个 ReduxActions 的实现。 Actions 是什么 middleware 和 UI 组件调用改变 Redux 存储器状态的方法。 通过扩展 ReduxActions,`built_redux` 生成器将生成所需的 boilerplate 来创建每个动作和一个 ActionNames 类。 ActionNames 类用于注册 reducer
abstract class CounterActions extends ReduxActions {
  ActionDispatcher&lt;int&gt; get increment;
  ActionDispatcher&lt;int&gt; get decrement;

  // 工厂来创建一个生成的 ReduxActions 实现实例
  CounterActions._();
  factory CounterActions() =&gt; _$CounterActions();
}

// 这是一个 built value. 它是一个实现了 Built 接口的不可变模型.
// Redux 存储器中的所有状态都包含在一个单一的 built value 模型中。
abstract class Counter implements Built&lt;Counter, CounterBuilder&gt; {
  /// [count] 计数器的值
  int get count;

  // Built value 构造函数. 工厂返回默认状态
  Counter._();
  factory Counter() =&gt; _$Counter._(count: 0);
}

// 这些是 reducer 函数. 它们具有 (state, action, builder) =&gt; void 签名.
// 它描述了如何通过应用变化到提供的 builder 中来将动作转换为下一个状态.
// 必须使用提供的 builder 调用 state.rebuild,这将不会更新存储器中的状态。
void increment(Counter state, Action&lt;int&gt; action, CounterBuilder builder) =&gt;
    builder.count = state.count + action.payload;

void decrement(Counter state, Action&lt;int&gt; action, CounterBuilder builder) =&gt;
    builder.count = state.count - action.payload;

// 这是一个 reducer builder. 使用 ReducerBuilder 是不是必需的,但是强烈推荐,因为它提供了静态类型检查,确保动作名称提供的 payload 与传递给您的 reducer 的预期 payload 相同. 调用 .build() 返回一个 reducer 函数,可以传递给存储器的构造函数。
final reducerBuilder = ReducerBuilder&lt;Counter, CounterBuilder&gt;()
  ..add(CounterActionsNames.increment, increment)
  ..add(CounterActionsNames.decrement, decrement);

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用built_redux进行状态管理的代码示例。built_redux结合了built_valueredux库,提供了不可变数据结构和可预测的状态管理。

1. 添加依赖

首先,在pubspec.yaml文件中添加必要的依赖:

dependencies:
  flutter:
    sdk: flutter
  built_value: ^8.0.0
  built_collection: ^5.0.0
  redux: ^5.0.0
  built_redux: ^8.0.0
  flutter_redux: ^0.6.0

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

2. 定义不可变数据模型

使用built_value定义不可变数据模型。例如,定义一个简单的用户状态:

import 'package:built_value/built_value.dart';
import 'package:built_collection/built_collection.dart';

part 'user_state.g.dart';

abstract class UserState implements Built<UserState, UserStateBuilder> {
  String get username;
  int get age;

  UserState._();
  factory UserState([void Function(UserStateBuilder) updates]) = _$UserState;
}

然后运行flutter pub run build_runner build来生成user_state.g.dart文件。

3. 定义Action

定义一些Action来修改状态:

import 'package:built_redux/built_redux.dart';
import 'user_state.dart';

class UpdateUsernameAction extends ReduxAction<UserState> {
  final String username;

  UpdateUsernameAction(this.username);

  @override
  UserState reduce() {
    UserStateBuilder builder = state.rebuild();
    builder.username = username;
    return builder.build();
  }
}

class UpdateAgeAction extends ReduxAction<UserState> {
  final int age;

  UpdateAgeAction(this.age);

  @override
  UserState reduce() {
    UserStateBuilder builder = state.rebuild();
    builder.age = age;
    return builder.build();
  }
}

4. 创建Reducer

定义一个Reducer来处理这些Action:

import 'package:built_redux/built_redux.dart';
import 'user_state.dart';
import 'actions.dart'; // 假设上面的Action类在这个文件中

UserState appReducer(UserState state, ReduxAction action) {
  if (action is UpdateUsernameAction) {
    return action.reduce();
  } else if (action is UpdateAgeAction) {
    return action.reduce();
  }
  return state;
}

5. 设置Store

创建Store并初始化状态:

import 'package:redux/redux.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'user_state.dart';
import 'reducer.dart'; // 假设上面的Reducer在这个文件中

void main() {
  UserState initialState = UserState(username: "Alice", age: 30);
  Store<UserState> store = Store<UserState>(appReducer, initialState: initialState);

  runApp(StoreProvider<UserState>(
    store: store,
    child: MyApp(),
  ));
}

6. 在Flutter Widget中使用Store

在Flutter Widget中连接Store并使用状态:

import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'user_state.dart';
import 'actions.dart'; // 假设Action类在这个文件中

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('built_redux Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Username: ${store.state.username}'),
              Text('Age: ${store.state.age}'),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  store.dispatch(UpdateUsernameAction("Bob"));
                },
                child: Text('Update Username'),
              ),
              ElevatedButton(
                onPressed: () {
                  store.dispatch(UpdateAgeAction(25));
                },
                child: Text('Update Age'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class MyAppWithStore extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StoreConnector<UserState, _ViewModel>(
      converter: (Store<UserState> store) {
        return _ViewModel(
          username: store.state.username,
          age: store.state.age,
        );
      },
      builder: (BuildContext context, _ViewModel vm) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('built_redux Example'),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('Username: ${vm.username}'),
                  Text('Age: ${vm.age}'),
                  SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: () {
                      StoreProvider.of<UserState>(context).dispatch(UpdateUsernameAction("Bob"));
                    },
                    child: Text('Update Username'),
                  ),
                  ElevatedButton(
                    onPressed: () {
                      StoreProvider.of<UserState>(context).dispatch(UpdateAgeAction(25));
                    },
                    child: Text('Update Age'),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}

class _ViewModel {
  final String username;
  final int age;

  _ViewModel({required this.username, required this.age});
}

注意:在上面的代码中,MyApp是一个简单的示例,展示了如何在不使用StoreConnector的情况下直接访问Store。然而,在真实的应用中,推荐使用StoreConnector来连接Store,以便更好地管理Widget的重建和状态更新。因此,更推荐使用MyAppWithStore这个示例。

这个示例展示了如何在Flutter中使用built_redux进行状态管理,包括定义不可变数据模型、创建Action和Reducer、设置Store以及在Widget中使用Store。希望这对你有所帮助!

回到顶部