inherited_store 0.4.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 62

inherited_store #

An inherited widget that holds data and rebuilds the widgets whom depend on the changed data.

This package uses InharitedModel as its base.

Advantages #

  1. lightweight (~100 lines of code)
  2. uses flutter's own InheritedModel & InheritedModel for detecting what needs to be rebuilt.
  3. no boilerplate code

Disadvantages #

  1. no computed values
  2. using keys is annoying

Example #

The code for the example is in the example tab.

Getting Started #

Step 1: Wrap your app with Store #

    Store(
      data: {
        'counter': 1,
      },
      child: MaterialApp(
        /* ... */
      ),
    );

Step 2: Use it #

class CounterText extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return Text(Store.of(context, 'counter').get().toString()); 
  }
}

If you edit counter using Store.of(context,'counter').set(2) the CounterText widget will be automatically rebuilt.

What exactly gets rebuilt? #

When you call Store.of(context,key) all the widgets that use the current context will be subscribed to changes for that key. If the value for the key changes the widget that uses the subscribed context will be rebuilt.

In the Example bellow, when the counter is modified, only the text widget inside the builder gets updated because it was subscribed using the c context and only decedents of c will be rebuilt. If instead of calling Store.of(c,'counter') we called Store.of(context,'counter'), when counter changes, the entire widget will get rebuilt and the text that shows the time will also update.

class StoreText extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text(DateTime.now().toString()), // show the time which this text widget was built
        Builder(builder: (c) {
          return Text(Store.of(c, 'counter').get().toString());
        }),
      ],
    );
  }
}

Example use cases #

UnMutable Data Management #

Things that are stored in the data map should only be replaced with the set method.

  Store(
    data: {
       UnmodifiableListView<Post> : UnmodifiableListView<Post>([]), // using add on a list will not notify subscribers
       User : User.getSavedUser(), 
       MyService : MyService(),
       AppTheme : AppTheme(),
       420 : false, // a key can be anything
       'balance' : 12000,
    },
    child: MaterialApp(
      /* ... */
    ),
  );

Managing App Preferences #

You can use Inherited_Store to effectively manage your app preferences. Load your preferences into the data field of the store then update the stored preferences using the onValueModified callback.

[0.4.0] #

  • added Store.get(context, key)
  • added Store.set(context, ket, newValue)

[0.3.0] #

  • dynamic keys

[0.1.0] #

  • readme update
  • name changes

[0.0.1] #

  • initial release.

example/main.dart

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

void main() => runApp(SettingsApp());

class SettingsApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Store(
      data: {
        'counter': 1,
        'counter2': 1,
      },
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: MainPage(),
      ),
    );
  }
}

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(32.0),
            child: SettingsDisplay(),
          ),
          Expanded(
            child: Row(
              children: <Widget>[
                Expanded(
                  child: Counter(
                    stKy: 'counter',
                  ),
                ),
                Expanded(
                  child: Counter(
                    stKy: 'counter2',
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            child: Row(
              children: <Widget>[
                Expanded(
                  child: StoreText(
                    storeKey: 'counter2',
                  ),
                ),
                Expanded(
                  child: StoreText(
                    storeKey: 'counter',
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class SettingsDisplay extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
        children: InheritedStore.of(context)
            .data
            .entries
            .map((e) => Text('${e.key} : ${e.value}'))
            .toList());
  }
}

class StoreText extends StatelessWidget {
  final String storeKey;

  const StoreText({Key key, this.storeKey}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        FutureBuilder(
            future: Future.delayed(Duration(milliseconds: 600)),
            builder: (c, s) {
              if (s.connectionState != ConnectionState.done) {
                return CircularProgressIndicator();
              }
              return Text(Store.of(context, storeKey).get().toString());
            }),
        Container(),
      ],
    );
  }
}

class Counter extends StatelessWidget {
  final String stKy;

  const Counter({Key key, this.stKy}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          FutureBuilder(
            future: Future.delayed(Duration(milliseconds: 600)),
            builder: (context, s) {
              if (s.connectionState != ConnectionState.done)
                return CircularProgressIndicator();
              return Text(Store.of(context, stKy).get().toString());
            },
          ),
          RaisedButton(
            child: Text('increment'),
            onPressed: () {
              Store.of(context, stKy).set(Store.of(context, stKy).get() + 1);
            },
          ),
        ],
      ),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  inherited_store: ^0.4.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:inherited_store/inherited_store.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
24
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
62
Learn more about scoring.

We analyzed this package on Apr 7, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Health suggestions

Format lib/src/store.dart.

Run flutter format to format lib/src/store.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test