{"id":19068052,"url":"https://github.com/ensody/reactive_state","last_synced_at":"2026-01-11T13:37:57.379Z","repository":{"id":56830188,"uuid":"198620349","full_name":"ensody/reactive_state","owner":"ensody","description":"An easy to understand reactive state management solution for Flutter.","archived":false,"fork":false,"pushed_at":"2020-04-01T09:13:39.000Z","size":113,"stargazers_count":18,"open_issues_count":3,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-18T16:21:10.441Z","etag":null,"topics":["dart","flutter","flutter-package","flutter-plugin","mobile","mobile-development","observable","observer-pattern","state","state-management"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/reactive_state","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ensody.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-24T11:16:39.000Z","updated_at":"2023-09-08T17:56:10.000Z","dependencies_parsed_at":"2022-09-02T04:00:31.584Z","dependency_job_id":null,"html_url":"https://github.com/ensody/reactive_state","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ensody%2Freactive_state","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ensody%2Freactive_state/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ensody%2Freactive_state/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ensody%2Freactive_state/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ensody","download_url":"https://codeload.github.com/ensody/reactive_state/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251319605,"owners_count":21570427,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","flutter","flutter-package","flutter-plugin","mobile","mobile-development","observable","observer-pattern","state","state-management"],"created_at":"2024-11-09T01:03:36.294Z","updated_at":"2026-01-11T13:37:57.369Z","avatar_url":"https://github.com/ensody.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# reactive_state\n\n[![Pub](https://img.shields.io/pub/v/reactive_state.svg)](https://pub.dev/packages/reactive_state)\n[![Build Status](https://travis-ci.com/ensody/reactive_state.svg?branch=master)](https://travis-ci.com/ensody/reactive_state)\n\nAn easy to understand reactive state management solution for Flutter.\n\n## Principles\n\n### Observable state\n\nState is held in one or multiple instances of `Value` or similar classes implementing `ValueNotifier`.\nThese are standard Flutter interfaces that everybody knows from `TextEditingController`, `Animation`, etc.\n\nAdditionally, you can use `ListValue` and `MapValue` for creating observable `List` and `Map` values that can notify you about fine-grained change events (instead of the whole value changing).\n\n### Reactive widgets\n\n`AutoBuild` automatically rebuilds your widgets when a `ValueNotifier` (or any `Listenable`) triggers a notification. It's similar to Flutter's `ValueListenableBuilder`, but it can track multiple dependencies and also works with `Listenable`.\n\nNo need to call `addListener`/`removeListener`. Just `get()` the value directly while `AutoBuild` takes care of tracking your dependencies.\n\nUnlike `InheritedWidget` and `Provider` you get fine-grained control over what gets rebuilt.\n\nStandard Flutter classes like `TextEditingController` and `Animation` implement `ValueListenable` and thus work nicely with `AutoBuild`.\n\n### Derived/computed state\n\n`DerivedValue` is an observable value that is computed (derived) from other observable values.\n\nAlso, `ListValue` and `MapValue` provide `.map()` and other operations for creating derived containers that keep themselves updated on a per-element basis.\n\n### Less boilerplate and indirection\n\nThe resulting code is much simpler than the same solution in [BLoC](https://www.didierboelens.com/2018/08/reactive-programming---streams---bloc/) or Redux.\n\n* No streams, no `StreamBuilder`, no asynchronous loading of widgets (unless you really need it).\n* No special event objects, no event handlers with long `switch()` statements.\n\n## Usage\n\nNote: Also see [reference](https://pub.dev/documentation/reactive_state/latest/) for details.\n\nA simple `AutoBuild` example:\n\n```dart\nimport 'package:flutter/material.dart';\nimport 'package:reactive_state/reactive_state.dart';\n\nclass MyPage extends StatelessWidget {\n  MyPage({Key key, @required this.counter}) : super(key: key);\n\n  final ValueNotifier\u003cint\u003e counter;\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: Text('Counter')),\n      body: Column(\n        children: \u003cWidget\u003e[\n          AutoBuild(builder: (context, get, track) {\n            return Text('Counter: ${get(counter)}');\n          }),\n          MaterialButton(\n            onPressed: () =\u003e counter.value++,\n            child: Text('Increment'),\n          ),\n        ],\n      ),\n    );\n  }\n}\n```\n\nNote that in real-world applications you shouldn't directly mutate the state, but instead put that into separate methods e.g. on an object made accessible through the [provider](https://pub.dev/packages/provider) package.\n\nAlso, take a look at the [example](https://github.com/ensody/reactive_state/blob/master/example/lib/main.dart) in the repo.\n\n## autoRun and AutoRunner\n\nOutside of widgets you might still want to react to state changes.\nYou can do that with `autoRun()` and `AutoRunner` (see [reference](https://pub.dev/documentation/reactive_state/latest/) for details).\n\n## Value vs ValueNotifier\n\nAs an alternative to `ValueNotifier` you can also use `reactive_state`'s `Value` class which provides an `update()` method for modifying more complex objects:\n\n```dart\nclass User {\n  String name = '';\n  String email = '';\n  // ...\n}\n\nvar userValue = Value(User());\nuserValue.update((user) {\n  user.name = 'Adam';\n  user.email = 'adam@adam.com';\n});\n```\n\nThis is similar to calling `setState()` with `StatefulWidget`.\nWith `update()` you can change multiple attributes and `Value` will trigger a single notification once finished - even if nothing was changed (so you don't need to implement comparison operators for complex objects).\n\n## DerivedValue\n\n`DerivedValue` is a dynamically calculated `ValueListenable` that updates its value whenever its dependencies change:\n\n```dart\nvar user = Value(User());\nvar emailLink = DerivedValue((get, track) =\u003e 'mailto:${get(user).email}');\n```\n\nHere, `emailLink` can be observed on its own and is updated whenever `user` is modified.\n\n## ListValue and MapValue\n\nA simple example showing a few things that can be done:\n\n```dart\nfinal listValue = ListValue(\u003cint\u003e[]);\nfinal mappedList = listValue.map((x) =\u003e x.toString());\nfinal listToMap = mappedList.toMap((x) =\u003e MapEntry(2 * int.parse(x), x));\nfinal invertedMap = listToMap.map((k, v) =\u003e MapEntry(v, k));\n\nlistValue.addAll([4, 1]);\n// =\u003e invertedMap.value == {'4': 8, '1': 2}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fensody%2Freactive_state","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fensody%2Freactive_state","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fensody%2Freactive_state/lists"}