inherited_builder

🤖Autogenerated state management and dependency injection with inherited widgets

MIT License

Stars
15

Inherited Builder

Autogenerated state management and dependency inhection with inherited widgets

ToC

Motivation

InheritedWidget is a powerful concept which allows you to inject values and pass them down the widget tree as well as subscribe to updates, but it requires a lot of boilerplate

This package allows you to get advantage of this awesome concept w/o boilerplate, it will be autogenerated for you

App Reference Architecture

Check out app reference architecture

Example app

"flutter create" app built with inherited_builder

Installation

dev_dependencies:
  build_runner: <version>
  inherited_builder: ^1.0.0

Usage

Define your model

app_state.dart

import 'package:flutter/material.dart';
import 'package:inherited_builder/annotations.dart';

part 'app_state.g.dart'

@Inherited()
class AppState {
    final int count;

    const AppState({ this.count });

    String toString() {
        return 'Count is $count';
    }
}

Execute build_runner

flutter packages pub run build_runner build --delete-conflicting-outputs

This will generate AppStateBuilder and AppStateProvider classes

Place Builder in your widget tree

import 'package:flutter/material.dart';

class ParentWidget extends StatelessWidget {
  final Widget child;

  const ParentWidget({Key key, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    const initialValue = 0;

    return AppStateBuilder(
      count: initialValue,
      child: child,
    );
  }
}

Access values using Provider

class ChildWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appStateProvider = AppStateProvider.of(context);

    return Scaffold(
      body: Center(child: Text(appStateProvider.count.toString())),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          final count = appStateProvider.count;
          appStateProvider.setcount(count + 1);
        },
      ),
    );
  }
}

Access instance of your model using Provider

class ChildWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appStateProvider = AppStateProvider.of(context);
+   final appState = appStateProvider.model;

    return Scaffold(
-     body: Center(child: Text(appStateProvider.count.toString())),
+     body: Center(child: Text(appState.toString())),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          final count = appStateProvider.count;
          appStateProvider.setcount(count + 1);
        },
      ),
    );
  }
}

React to changes

You can use didChangeDepencies() to react to changes of your model (e.g. appStateProvider.setCount(newCount))

Example:

import 'package:flutter/material.dart';

class StatePersistance extends StatefulWidget {
  final Widget child;

  const StatePersistance({Key key, this.child}) : super(key: key);

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

class _StatePersistanceState extends State<StatePersistance> {
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }

  @override
  void didChangeDependencies() async {
    final appStateProvider = AppStateProvider.of(context);

    final currentState = appStateProvider.model;
    final prevState = appStateProvider.oldModel;

    if (currentState.count != prevState.count) {
        persist(currentState);
    }

    super.didChangeDependencies();
  }
}

Define actions on your model

requires dart >2.7.0

import 'package:flutter/material.dart';
import 'package:inherited_builder/annotations.dart';

@Inherited()
class AppState {
    final int count;

    const AppState({ this.count });

    String toString() {
        return 'Count is $count';
    }
}

extension CounterActions on AppStateProvider {
    increment() {
        this.setCount(this.count + 1);
    }
}

// somewhere in the widget tree:

final appStateProvider = AppStateProvider.of(context);
appStateProvider.increment();

License

MIT

Package Rankings
Top 22.49% on Pub.dev
Badges
Extracted from project README's
lesnitsky.dev GitHub stars Twitter Follow lesnitsky.dev GitHub stars Twitter Follow