패키지, 저장소 및 앱 카테고리 검색

패키지 상세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을 사용합니다
  • DI를 위한 내장 서비스 로케이터
  • 최소한의 보일러플레이트
  • 상태 변경 시 위젯 자동 재구성
  • 깔끔하고 읽기 쉬운 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.

카테고리

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.