Flutter状态管理插件state_x的使用

Flutter状态管理插件StateX的使用

StateX 是一个用于简化和集中状态管理的库。它通过在单个存储(store)中进行状态管理来提高性能,因为构建器只处理特定范围内的变化,避免了整个小部件树的重新构建。

示例代码

示例代码

// 模拟的仓库类,用于示例
class Repository {
  Future<bool> authUser(String email, String passwold) async {
    await Future.delayed(Duration(seconds: 3));
    return true;
  }
}

// 这样我们就创建了一个新的视图模型,其中将集中管理主页的状态
class HomeViewModel extends StateXStore {
  // 以这种方式创建一个新的属性,该属性由StateX管理
  late final xEmail = StateX.of(this)("");
  late final xPassword = StateX.of(this)("");
  late final xUserStatus = StateX.of(this)("请登录");

  final repo = Repository();

  set email(String value) => xEmail.value = value;
  String get email => xEmail.value;

  set password(String value) => xPassword.value = value;
  String get password => xPassword.value;

  set userStatus(String value) => xUserStatus.value = value;
  String get userStatus => xUserStatus.value;

  bool get isValid => email.isNotEmpty && password.isNotEmpty;

  void auth() async {
    // 这里表示视图处于加载状态
    setLoading(true);
    if (await repo.authUser(email, password)) {
      xUserStatus.value = "用户已登录";
      // 这里表示视图可以取消加载状态
      setLoading(false);
    } else {
      // 如果出现错误,则设置异常
      setError(Exception("邮箱或密码无效"));
    }
  }
}

void main() {
  // 这里添加全局观察者,用于应用程序状态的管理和错误日志记录
  StateXGlobalObserver.listen((type, state) => print(type));
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'StateX',
      theme: ThemeData(primarySwatch: Colors.blue, accentColor: Colors.white),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  [@override](/user/override)
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  var viewModel = HomeViewModel();

  [@override](/user/override)
  void initState() {
    // 这里添加一个观察者,用于错误管理,但任何状态的变化都会通过这里
    viewModel.addObserver((type, state, key) => print(key == viewModel.xEmail.key));
    super.initState();
  }

  [@override](/user/override)
  dispose() {
    viewModel.dispose();
    super.dispose();
  }

  Widget _buildButton(bool inLoading) {
    Widget buttonChild = inLoading
        ? SizedBox(
            width: 20,
            height: 20,
            child: CircularProgressIndicator(
              color: Colors.white,
            ))
        : Text("进入");
    return Container(
      width: double.infinity,
      height: 48,
      child: ElevatedButton(
        onPressed: viewModel.isValid ? viewModel.auth : null,
        child: buttonChild,
      ),
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("StateX"),
        ),
        body: Padding(
          padding: const EdgeInsets.all(21),
          child: Center(
            child: SingleChildScrollView(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  // 使用 scoped builder 的示例
                  StateXScopedBuilder(
                    // 指定哪个 store 将管理此范围内的更改
                    store: viewModel,
                    // 可选参数。指定要监听哪些属性的状态更改,如果不传递此参数,scoped 将在每次 store 更改时重建
                    states: [viewModel.xUserStatus],
                    onState: () => Text(
                      viewModel.userStatus,
                    ),
                  ),
                  TextField(
                    onChanged: (value) {
                      viewModel.email = value;
                    },
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  TextField(
                    onChanged: (value) {
                      viewModel.password = value;
                    },
                  ),
                  SizedBox(
                    height: 20,
                  ),

                  // 使用 scoped builder 的另一个示例
                  StateXScopedBuilder(
                    // 指定哪个 store 将管理此范围内的更改
                    store: viewModel,
                    // 可选参数。指定要监听哪些属性的状态更改,如果不传递此参数,scoped 将在每次 store 更改时重建
                    states: [viewModel.xEmail, viewModel.xPassword],
                    onLoading: () => _buildButton(true),
                    onState: () => _buildButton(false),
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  // 使用 state builder 的示例
                  StateXBuilder(
                    // 指定哪个 store 将管理此 builder 中的更改
                    store: viewModel,
                    // 可选参数。指定要监听哪些属性的状态更改,如果不传递此参数,scoped 将在每次 store 更改时重建
                    states: [viewModel.xEmail, viewModel.xPassword],
                    // 参数指示当 store 处于加载状态时将重建
                    includeLoading: true,
                    builder: (context, snapshot) {
                      return _buildButton(snapshot.type == StateXType.isLoading);
                    },
                  )
                ],
              ),
            ),
          ),
        ));
  }
}

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

1 回复

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


当然,关于Flutter中的状态管理插件state_x(注意:state_x并不是一个官方或广泛认可的插件名称,这里我假设它是一个自定义或第三方状态管理库,用于演示目的),我可以为你提供一个假设性的使用案例。通常,状态管理库会提供一些核心功能,比如创建全局状态、监听状态变化以及更新状态。以下是一个假设性的state_x插件的使用示例:

假设的state_x插件安装

首先,你需要在pubspec.yaml文件中添加state_x依赖(注意:这只是一个假设的依赖名称,实际使用时请替换为真实的插件名称):

dependencies:
  flutter:
    sdk: flutter
  state_x: ^1.0.0  # 假设的版本号

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

使用state_x进行状态管理

1. 创建全局状态

假设state_x提供了一个StateContainer类来管理全局状态,你可以这样创建一个状态容器:

import 'package:state_x/state_x.dart';

class CounterState {
  int count = 0;
}

final counterStateContainer = StateContainer<CounterState>(initialState: CounterState());

2. 提供状态给MaterialApp

main.dart中,使用StateProvider将状态容器提供给整个应用:

import 'package:flutter/material.dart';
import 'package:state_x/state_x.dart';
import 'counter_state.dart';  // 假设这是上面代码所在的文件

void main() {
  runApp(StateProvider<CounterState>(
    stateContainer: counterStateContainer,
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('State X Example'),
        ),
        body: Center(
          child: CounterWidget(),
        ),
      ),
    );
  }
}

3. 使用状态

CounterWidget中,使用StateSelector来获取和监听状态:

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

class CounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StateSelector<CounterState>(
      selector: (state) => state.count,
      builder: (context, count) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$count',
              style: Theme.of(context).textTheme.headline4,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                context.read<StateContainer<CounterState>>().updateState((state) {
                  state.count++;
                });
              },
              child: Text('Increment'),
            ),
          ],
        );
      },
    );
  }
}

在这个示例中,StateSelector用于从StateContainer中获取count状态,并在按钮点击时更新该状态。注意,这里假设StateContainer提供了一个updateState方法来更新状态,这只是一个假设性的API设计。

注意事项

  • 由于state_x是一个假设的插件名称,因此上述代码中的类和方法(如StateContainer, StateSelector, updateState等)都是假设性的,实际使用时请参考state_x插件的官方文档。
  • 在实际项目中,请确保使用经过验证和广泛使用的状态管理库,如Provider, Riverpod, GetXBloc等。

希望这个假设性的示例能帮助你理解如何在Flutter中使用一个假设的状态管理插件。如果你有具体的插件名称或API文档,可以提供更多详细信息,以便给出更准确的示例。

回到顶部