Flutter状态管理插件restate的使用

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

Flutter状态管理插件restate的使用

Restate简介

Restate 是一个用于Flutter应用程序的响应式状态管理库,它没有任何依赖,并且代码量小于200行。每个 StateBloc 持有一个可以同步访问、作为 Future 或者作为 Stream 的单个状态值。

  • StateBloc.value - 同步返回当前状态值。
  • StateBloc.current - 返回一个 Future,如果已经有值则立即解析为当前值,否则等待值被添加。
  • StateBloc.stream - 返回一个包含状态值更新的 Stream
  • StateBloc.changes - 返回一个包含状态值变化(包括当前和前一个值)的 Stream

读取当前值

import 'package:restate/restate.dart';

final counterState = StateBloc<int>(0);
print(counterState.value); // 0
counterState.add(1);
print(counterState.value); // 1

监听值的流

import 'package:restate/restate.dart';

final counterState = StateBloc<int>(0);

counterState.stream.listen((value) {
  print(value);
  // 0
  // 1
  // 2
});

counterState.add(1);
counterState.add(2);

监听值的变化

import 'package:restate/restate.dart';

final counterState = StateBloc<int>(0);

counterState.changes.listen((value) {
  print('${value.previous}->${value.current}');
  // null->0
  // 0->1
  // 1->2
});

counterState.add(1);
counterState.add(2);

等待当前值

import 'package:restate/restate.dart';

final counterState = StateBloc<int>();

counterState.current.then((value) => print(value)); // 1
counterState.add(1);
counterState.current.then((value) => print(value)); // 1

在Widgets中访问状态

通过创建 StateBloc 并使用 StreamBuilder 来在数据变化时重建Widget:

final counterStateBloc = StateBloc<int>(0);

class MyWidget extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: counterStateBloc.stream,
      builder: (context, counterSnap) {
        if (!counterSnap.hasData) {
          return Text('Waiting for value...');
        }

        final counter = counterSnap.data;

        return Column(
          children: [
            Text('Counter: $counter'),
            ElevatedButton(
              onPressed: () {
                counterStateBloc.add(counter + 1);
              },
              child: Text('Increment'),
            ),
          ],
        );
      },
    );
  }
}

更新StateBloc的值

通常情况下,使用 StateBloc.add API 就足够了。但有时你可能需要处理复杂对象的变更。为了保持状态值的不可变性,可以使用 copyWith 方法来返回新对象:

class User {
  String firstName;
  String lastName;

  User({
    required this.firstName,
    required this.lastName,
  });

  User copyWith({
    String? firstName,
    String? lastName,
  }) {
    return User(
      firstName: firstName ?? this.firstName,
      lastName: lastName ?? this.lastName,
    );
  }
}

final user = User(firstName: 'Anakin', lastName: 'Skywalker');
final userState = StateBloc<User>(user);

userState.add(
  userState.value.copyWith(
    firstName: 'Darth',
    lastName: 'Vader',
  ),
);

如果你需要直接修改当前值,可以使用 StateBloc.setValue API:

final user = User(firstName: 'Anakin', lastName: 'Skywalker');
final userState = StateBloc<User>(user);

userState.setValue((currentUser) {
  currentUser.firstName = 'Darth';
  currentUser.lastName = 'Vader';
});

完整示例Demo

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

import 'package:flutter/material.dart';
import 'package:restate/restate.dart';
import 'package:restate/state_change_tuple.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

StateBloc<int> _counterBloc = StateBloc<int>(0);

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ElevatedButton(
              onPressed: () {
                _counterBloc.add((_counterBloc.value ?? 0) + 1);
              },
              child: const Text('Increment count'),
            ),
            const SizedBox(height: 16),
            StreamBuilder<int?>(
              stream: _counterBloc.stream,
              builder: (context, counterBlocSnap) {
                if (!counterBlocSnap.hasData) {
                  return const SizedBox();
                }

                final clickedCount = counterBlocSnap.data!;

                return Text('Clicked $clickedCount times');
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16),
              child: FutureBuilder<int?>(
                future: _counterBloc.current,
                builder: (context, counterBlocSnap) {
                  if (!counterBlocSnap.hasData) {
                    return const Text('The counter has not been clicked.');
                  }

                  final clickedCount = counterBlocSnap.data;

                  if (clickedCount == 0) {
                    return const Text('The counter has not been clicked.');
                  }

                  return const Text('The counter has been clicked!');
                },
              ),
            ),
            StreamBuilder<StateChangeTuple?>(
              stream: _counterBloc.changes,
              builder: (context, counterChangeBlocSnap) {
                if (!counterChangeBlocSnap.hasData) {
                  return const SizedBox();
                }

                final clickCountChange = counterChangeBlocSnap.data!;

                return Text(
                  'Changed from ${clickCountChange.previous ?? 0} to ${clickCountChange.current}',
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter中使用restate插件进行状态管理的示例代码。restate是一个轻量级的状态管理库,它允许你在Flutter应用中轻松地共享和更新状态。

首先,确保你已经将restate添加到你的pubspec.yaml文件中:

dependencies:
  flutter:
    sdk: flutter
  restate: ^x.y.z  # 请替换为最新版本号

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

1. 创建一个Restate Store

首先,我们需要创建一个Store来管理我们的状态。在这个例子中,我们将创建一个简单的计数器状态。

// counter_store.dart
import 'package:restate/restate.dart';

class CounterStore extends Store {
  int count = 0;

  void increment() {
    count += 1;
    update();  // 通知监听器状态已更改
  }

  void decrement() {
    count -= 1;
    update();  // 通知监听器状态已更改
  }
}

2. 使用RestateProvider提供Store

接下来,我们需要在应用的顶层使用RestateProvider来提供我们的CounterStore

// main.dart
import 'package:flutter/material.dart';
import 'package:restate/restate.dart';
import 'counter_store.dart';

void main() {
  runApp(
    RestateProvider(
      store: CounterStore(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CounterScreen(),
    );
  }
}

3. 连接到Store并更新UI

现在,我们可以在我们的CounterScreen中使用useStore钩子来连接到CounterStore并更新UI。

// counter_screen.dart
import 'package:flutter/material.dart';
import 'package:restate/hooks.dart';
import 'counter_store.dart';

class CounterScreen extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final counterStore = useStore<CounterStore>();

    return Scaffold(
      appBar: AppBar(
        title: Text('Counter App'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '${counterStore.count}',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          counterStore.increment();
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

4. 运行应用

现在,你可以运行你的Flutter应用,并看到一个简单的计数器应用,其中包含一个按钮和一个显示计数值的文本。每次点击按钮时,计数值都会增加,并且UI会自动更新以反映最新的状态。

这个示例展示了如何使用restate进行基本的状态管理。restate还提供了更多高级功能,如嵌套状态、异步操作等,你可以根据需要进一步探索和使用这些功能。

回到顶部