Flutter状态管理插件typed_redux的使用

Flutter状态管理插件typed_redux的使用

typed_reduxredux 包的一个类型安全版本。它消除了使用 dynamic 类型的情况,使得状态(State)、缩减器(Reducer)和中间件(Middleware)都能够明确知道动作(Action)的类型。

感谢原版包的作者们。

完整示例代码

以下是一个完整的示例代码,展示了如何在 Flutter 应用中使用 typed_redux 进行状态管理。

import 'package:flutter/material.dart';
import 'package:redux/redux.dart';
import 'package:typed_redux/typed_redux.dart';

// 定义一个简单的状态类
class CounterState {
  final int count;

  CounterState({required this.count});

  CounterState copyWith({int? count}) {
    return CounterState(count: count ?? this.count);
  }
}

// 定义一个动作类
class IncrementAction {}

class DecrementAction {}

// 定义缩减器
Reducer<CounterState> counterReducer = TypedReducer<CounterState, IncrementAction>(
      (state, action) => state.copyWith(count: state.count + 1),
    ) as Reducer<CounterState>;

counterReducer = TypedReducer<CounterState, DecrementAction>(
      (state, action) => state.copyWith(count: state.count - 1),
    ).update(counterReducer);

// 创建一个 Store
final store = Store<CounterState>(
  counterReducer,
  initialState: CounterState(count: 0),
);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StoreProvider<CounterState>(
      store: store,
      child: MaterialApp(
        home: CounterPage(),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Typed Redux Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            StreamBuilder<int>(
              stream: StoreProvider.of<CounterState>(context).stateStream,
              initialData: store.state.count,
              builder: (context, snapshot) {
                return Text(
                  'Count: ${snapshot.data}',
                  style: TextStyle(fontSize: 24),
                );
              },
            ),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                FloatingActionButton(
                  onPressed: () {
                    store.dispatch(IncrementAction());
                  },
                  child: Icon(Icons.add),
                ),
                FloatingActionButton(
                  onPressed: () {
                    store.dispatch(DecrementAction());
                  },
                  child: Icon(Icons.remove),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

代码解释

  1. 定义状态类:

    class CounterState {
      final int count;
    
      CounterState({required this.count});
    
      CounterState copyWith({int? count}) {
        return CounterState(count: count ?? this.count);
      }
    }
    

    这里定义了一个简单的状态类 CounterState,包含一个计数器变量 count

  2. 定义动作类:

    class IncrementAction {}
    
    class DecrementAction {}
    

    定义了两个动作类 IncrementActionDecrementAction,分别表示增加和减少的操作。

  3. 定义缩减器:

    Reducer<CounterState> counterReducer = TypedReducer<CounterState, IncrementAction>(
          (state, action) => state.copyWith(count: state.count + 1),
        ) as Reducer<CounterState>;
    
    counterReducer = TypedReducer<CounterState, DecrementAction>(
          (state, action) => state.copyWith(count: state.count - 1),
        ).update(counterReducer);
    

    使用 TypedReducer 来定义缩减器,根据不同的动作类型来更新状态。

  4. 创建 Store:

    final store = Store<CounterState>(
      counterReducer,
      initialState: CounterState(count: 0),
    );
    

    创建一个 Store 实例,用于存储应用的状态。

  5. 主应用:

    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return StoreProvider<CounterState>(
          store: store,
          child: MaterialApp(
            home: CounterPage(),
          ),
        );
      }
    }
    

    main() 函数中启动应用,并使用 StoreProviderStore 提供给整个应用。

  6. 展示页面:

    class CounterPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Typed Redux Example'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                StreamBuilder<int>(
                  stream: StoreProvider.of<CounterState>(context).stateStream,
                  initialData: store.state.count,
                  builder: (context, snapshot) {
                    return Text(
                      'Count: ${snapshot.data}',
                      style: TextStyle(fontSize: 24),
                    );
                  },
                ),
                SizedBox(height: 20),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    FloatingActionButton(
                      onPressed: () {
                        store.dispatch(IncrementAction());
                      },
                      child: Icon(Icons.add),
                    ),
                    FloatingActionButton(
                      onPressed: () {
                        store.dispatch(DecrementAction());
                      },
                      child: Icon(Icons.remove),
                    ),
                  ],
                ),
              ],
            ),
          ),
        );
      }
    }
    

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

1 回复

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


typed_redux 是一个用于 Flutter 应用的状态管理插件,它基于 Redux 模式,但提供了更强的类型安全性和更简洁的 API。通过使用 typed_redux,你可以更好地组织和管理应用的状态,同时确保代码的类型安全。

以下是如何在 Flutter 项目中使用 typed_redux 的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 typed_redux 依赖:

dependencies:
  flutter:
    sdk: flutter
  typed_redux: ^0.2.0

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

2. 定义状态(State)

在 Redux 中,状态是一个不可变的对象,通常是一个 Dart 类。你可以定义一个简单的状态类:

class AppState {
  final int counter;

  AppState({required this.counter});

  AppState copyWith({int? counter}) {
    return AppState(counter: counter ?? this.counter);
  }
}

3. 定义 Action

Action 是一个表示状态变化的简单对象。你可以定义一些 Action 类:

class IncrementAction {}

class DecrementAction {}

4. 定义 Reducer

Reducer 是一个纯函数,它接收当前状态和一个 Action,并返回一个新的状态。你可以定义一个 Reducer:

AppState reducer(AppState state, dynamic action) {
  if (action is IncrementAction) {
    return state.copyWith(counter: state.counter + 1);
  } else if (action is DecrementAction) {
    return state.copyWith(counter: state.counter - 1);
  }
  return state;
}

5. 创建 Store

Store 是 Redux 的核心,它持有应用的状态,并负责分发 Action 和更新状态。你可以创建一个 Store:

import 'package:typed_redux/typed_redux.dart';

final store = Store<AppState>(
  initialState: AppState(counter: 0),
  reducer: reducer,
);

6. 在 Flutter 中使用 Store

你可以使用 StoreProvider 将 Store 提供给整个应用,然后使用 StoreConnector 来连接 Store 和 UI:

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return StoreProvider<AppState>(
      store: store,
      child: MaterialApp(
        home: CounterScreen(),
      ),
    );
  }
}

class CounterScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Counter App')),
      body: Center(
        child: StoreConnector<AppState, int>(
          converter: (store) => store.state.counter,
          builder: (context, counter) {
            return Text(
              'Counter: $counter',
              style: TextStyle(fontSize: 24),
            );
          },
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            onPressed: () => store.dispatch(IncrementAction()),
            child: Icon(Icons.add),
          ),
          SizedBox(height: 10),
          FloatingActionButton(
            onPressed: () => store.dispatch(DecrementAction()),
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}
回到顶部