搜索插件、代码仓与 APP 分类

插件详情v2.1.0

inherited_state

基于 InheritedWidget 和依赖注入(DI)的简单且干净的状态管理,依赖于服务定位器模式。

AndroidiOSWebmacOSWindowsLinux
近 30 天下载
22
喜欢数
15
Pub 分数
150

安装插件

flutter pub add inherited_state

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

InheritedState 是一个轻量级的 Flutter 状态管理解决方案,利用 InheritedWidget 实现高效的组件树更新,并采用服务定位器模式进行依赖注入。它提供了一个简洁、简单的 API 来管理应用状态,无需样板代码,非常适合中小型应用程序。该包通过仅更新依赖于已更改状态的组件来确保最小化重建,同时还能轻松访问应用中共享的服务。它专为希望获得比更复杂状态管理方案更简单替代方案的开发者而设计。

适合场景

  • 简单的应用状态管理
  • Flutter 应用中的依赖注入
  • Provider 或 Riverpod 的轻量级替代方案
  • 在小部件树之间管理共享数据
  • 减少有状态小部件中的样板代码

主要特点

  • 使用 InheritedWidget 实现高效更新
  • 内置的服务定位器用于依赖注入
  • 最小化样板代码
  • 状态变化时自动重建部件
  • 简洁、可读的 API
  • 支持所有主要平台

适合对象

  • 寻求简洁的开发者
  • 中等状态复杂度的项目
  • 希望快速设置的团队
  • 需要依赖注入的应用程序
  • Flutter 初学者学习状态管理

使用建议

  • 不太适合非常大规模的应用
  • 与完整框架相比,高级功能有限
  • 需要理解 InheritedWidget
  • 可能需要额外的工具来进行测试
  • 比流行的替代方案少的社区支持

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

inherited_state

Simple scoped reactive state management (using [InheritedWidget]) and DI. Supports both immutable and mutable updates.

Quick Start

pubspec.yaml

inherited_state: ^2.1.0

Setup State Management

InheritedState widget needs to be part of the tree as an ancestor to be able to use it from the descendent widgets similar to the usage of InheritedWidget. You can register the reactive states using the states argument.

InheritedState(
    states: [
        Inject<Counter>(() => Counter(0)),
    ],
    builder: (_) =>
    ...
)
Reactive State - UI Change Notifications
// Plain dart class
class Counter {
    Counter(this.count);
    int count = 0;
}

// RS is an alias for ReactiveState.
void _incrementCounter() {
  // Immutable update
  final res = RS.set<Counter>(context, (counter) => Counter(counter.count + 1));
}

// Pass context to the `RS.get` method to subscribe to changes (widget automatically rebuilds when changes occur).
@override
Widget build(BuildContext context) {
    final counter = RS.get<Counter>(context);
    ...
}

Setup DI

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

void registerDependencies() {
  SL.register(
    () => const AppConfig(
      appName: 'Inherited State Example',
      baseUrl: 'https://reqres.in/api',
    ),
  );
  SL.register(() => ApiService(SL.get()));
  SL.register(() => CounterService(SL.get()));
}
Service Locator (DI) - Services, Configs, etc.
// SL is an alias for ServiceLocator.
final counterService = SL.get<CounterService>();

Full Example with Reactive states and Services

main.yaml
import 'package:flutter/material.dart';
import 'package:inherited_state/inherited_state.dart';

import 'models/counter.dart';
import 'services/api_service.dart';
import 'services/app_config.dart';
import 'services/counter_service.dart';

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

void registerDependencies() {
  SL.register(
    () => const AppConfig(
      appName: 'Inherited State Example',
      baseUrl: 'https://reqres.in/api',
    ),
  );
  SL.register(() => ApiService(SL.get()));
  SL.register(() => CounterService(SL.get()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return InheritedState(
        states: [
          Inject<Counter>(() => Counter(0)),
        ],
        builder: (_) {
          // final appConfig = InheritedService.get<AppConfig>();
          final appConfig = SL.get<AppConfig>();
          return MaterialApp(
            title: appConfig.appName,
            home: MyHomePage(title: appConfig.appName),
          );
        });
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final counterService = SL.get<CounterService>();
  Future<int> initialCounterFuture;

  @override
  void initState() {
    super.initState();
    initialCounterFuture = counterService.getInitialCounter();
    // Long form
    // initialCounterFuture.then((value) =>
    //     ReactiveService.getReactive<Counter>().setState((counter) => counter.count = value));
    // Short form - Mutatable update
    initialCounterFuture.then((value) =>
        RS.set<Counter>(context, (counter) => counter.count = value));
  }

  void _incrementCounter() {
    // Immutable update
    final res =
        RS.set<Counter>(context, (counter) => Counter(counter.count + 1));
    print('increment result: $res');
  }

  @override
  Widget build(BuildContext context) {
    final counter = RS.get<Counter>(context);
    print('rebuild: $counter');
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            const SizedBox(height: 20),
            _buildFutureWaiter(
                (isReady) => Text(
                      '${counter.count}',
                      style: Theme.of(context).textTheme.headline4,
                    ),
                true),
          ],
        ),
      ),
      floatingActionButton: _buildFutureWaiter(
        (isReady) {
          print('floats $counter');
          return FloatingActionButton(
            backgroundColor: isReady ? null : Colors.grey,
            disabledElevation: 0,
            onPressed: isReady ? _incrementCounter : null,
            tooltip: 'Increment',
            child: const Icon(Icons.add),
          );
        },
      ),
    );
  }

  Widget _buildFutureWaiter(Widget Function(bool isReady) builder,
          [bool showSpinner = false]) =>
      FutureBuilder<int>(
        future: initialCounterFuture,
        builder: (_, snapshot) => showSpinner && !snapshot.hasData
            ? const CircularProgressIndicator()
            : builder(snapshot.hasData),
      );
}


View file

Inherited State Widget

This widget is used to setup the reactive state instances available to the descendants. It can be used multiple times at different tree nodes.

Reactive State

Reactive state allows for subscriptions and updates to the underlying model in an immutable and mutable fashion depending on developer preference.

Services

ServiceLocator allows for a simple way of registering global dependencies that can be used anywhere within the app without relying on flutter context or any sort of UI related mechanism. Services can be accessed and referenced and the reference is always a singleton.

所属分类

源码仓库

使用此插件的项目

暂无相关数据。