Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Riki1312/state-provider

A super simple state management library for Flutter.
https://github.com/Riki1312/state-provider

dart flutter simple state-management

Last synced: about 2 months ago
JSON representation

A super simple state management library for Flutter.

Awesome Lists containing this project

README

        

# State Provider

A super simple state management library for [Flutter](https://flutter.dev/).

The whole implementation is less than 200 lines of code, including docs comments.
It uses no external libraries and is therefore really easy to integrate and debug.

Super simple doesn't mean poorly implemented, though. It's actually pretty powerful:

- ๐Ÿชจ Built around **immutable values**, making it easier to keep track of state changes.
- ๐ŸŒŒ Full **support for streams**, allows states to interact with each other.
- ๐Ÿ•น๏ธ Efficient separation of states data from states mutation logic.
- โœจ Convenient access to states directly from the context.
- ๐Ÿงน Automatic dispose of states when they are no longer used.

Inspired by popular libraries like [Provider](https://pub.dev/packages/provider)
and [Bloc](https://pub.dev/packages/bloc), but built around Flutter's existing
tools like `Listenable`, `StreamController`, and `InheritedNotifier`.

And it's fully covered by tests ๐Ÿ’ฏ.

## Getting Started

### Installation

Add this to your `pubspec.yaml` file:

```yaml
dependencies:
state_provider:
git:
url: https://github.com/Riki1312/state-provider.git
```

Then run `flutter pub get`.

### Counter example

Create a class that contains the counter state and extends `StateValue`.

```dart
class CounterState extends StateValue {
CounterState() : super(0);

void increment() {
value++;
}
}
```

Use the `StateProvider` widget to inject the state into the tree.

```dart
StateProvider(
state: CounterState(),
child: ...,
);
```

Retrieve the state from a descendant widget of the `StateProvider`.

(This uses the type of the state, in this case `CounterState`).

```dart
Builder(
builder: (context) => Text('${context.watch().value}'),
),

ElevatedButton(
onPressed: () {
context.read().increment();
},
child: ...,
),
```

The difference between `context.watch` and `context.read` is that `watch` rebuilds
the widget whenever the state value changes, while `read` only returns the state.

### Counter example with streams

Thanks to the streams we can extend the previous example by adding a second state
that works with the first to keep track of odd numbers inside a list.

```dart
class ListState extends StateValue> {
ListState(CounterState counterState) : super([]) {
sub = counterState.stream.where((number) => number.isOdd).listen((number) {
value = [...value, "Odd: $number"];
});
}

StreamSubscription? sub;

@override
Future onClose() async => sub?.cancel();
}
```

Let's add another `StateProvider` for the new state.

```dart
StateProvider(
state: ListState(context.read()),
child: ...,
),
```

Now we can use the new state in the widget tree.

```dart
Builder(
builder: (context) => Text('${context.watch().value}'),
),
```

### Counter example alternative

Instead of creating a new class for very simple cases, you can use `StateValue` directly.

```dart
StateProvider(
state: StateValue(0),
child: ...,
),
```

```dart
Builder(
builder: (context) => Text('${context.watch>().value}'),
),

ElevatedButton(
onPressed: () {
context.read>().value++;
},
child: ...,
),
```

## Contributing and Feedback

If you have any questions or suggestions, feel free to open an issue or a pull request.

## License

Licensed under the [MIT License](/LICENSE).