{"id":20664043,"url":"https://github.com/flutterando/rx_notifier","last_synced_at":"2025-04-19T16:12:34.500Z","repository":{"id":52972989,"uuid":"324660087","full_name":"Flutterando/rx_notifier","owner":"Flutterando","description":"Extension to ValueNotifier by transparently applying functional reactive programming (TFRP)","archived":false,"fork":false,"pushed_at":"2023-10-28T23:31:35.000Z","size":14312,"stargazers_count":42,"open_issues_count":2,"forks_count":12,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-01-08T19:55:01.571Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/rx_notifier","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/Flutterando.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-27T00:39:46.000Z","updated_at":"2024-05-04T20:35:04.000Z","dependencies_parsed_at":"2024-06-19T05:54:39.853Z","dependency_job_id":null,"html_url":"https://github.com/Flutterando/rx_notifier","commit_stats":{"total_commits":60,"total_committers":7,"mean_commits":8.571428571428571,"dds":0.1166666666666667,"last_synced_commit":"6bf23c4f357bbe94909103fcd93f222b50ab726b"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Frx_notifier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Frx_notifier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Frx_notifier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Frx_notifier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Flutterando","download_url":"https://codeload.github.com/Flutterando/rx_notifier/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234874641,"owners_count":18900008,"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":[],"created_at":"2024-11-16T19:21:50.995Z","updated_at":"2025-01-20T23:56:40.182Z","avatar_url":"https://github.com/Flutterando.png","language":"Dart","readme":"# rx_notifier\n\nThe [ValueNotifier](https://api.flutter.dev/flutter/foundation/ValueNotifier-class.html) is a simple, native form of Flutter reactivity.\nThis extension aims to transparently apply **functional reactive programming (TFRP)**.\n\n- [Read the documentation](https://github.com/Flutterando/rx_notifier/tree/master/rx_notifier).\n\n## Implementing the Atomic State.\n\nIt is possible to implement [Recoil](https://recoiljs.org) Atoms pattern using `RxNotifier`.\nThis pattern consists of the state being an object with its own reactivity.\n\n![atom](/assets/atom.png)\n\n\n## Motivation\n\nDevelopers still have trouble understanding state management in Flutter.\nWe had this conclusion after several research in the community fluttering and also\nin partner companies.\nAtomic State is a noob-friendly state management approuch at the same time\nthat maintains a reliable structure thinking of scalability and maintenance.\n\nMore details, read this [Medium article on the subject](https://medium.com/@jacobmoura/introdu%C3%A7%C3%A3o-ao-estado-at%C3%B4mico-no-flutter-com-rxnotifier-73ad9edf8718).\n\n\n## Rules\n\nWe must take into account some architectural limits to execute this Approach:\n\n1. All states must be an atom(`RxNotifier` instance).\n2. All actions must be an atom(`RxNotifier` instance).\n3. Business rules must be created in the `Reducer` and not in the Atom.\n\n\n## Layers\n\nWe will have 3 main layers, they are: `Atoms`, `Reducers` and `Views`;\n\n![atom](/assets/arch.png)\n\nNote that the View (which is the presentation layer) does not know about the Reducer (which is the business rule execution layer).\nThese two layers share atoms that in turn represent the state and the dispatch of state actions.\n\nIn Flutter these layers translate to Atom(`RxNotifier`), Reducer(RxReducer) and View(Widget):\n\n![atom](/assets/flutter-rx.png)\n\n\n## Atoms (RxNotifier)\n\nAtom represent the reactive state of an application.\nEach atom has its own reactivity.\n\n\n```dart\n// atoms\nfinal productsState = \u003cProduct\u003e[].asRx();\nfinal productTextFilterState = RxNotifier\u003cString\u003e('');\n\n// computed\nList\u003cProduct\u003e get filteredProductsState {\n     if(productTextFilterState.value.isEmpty()){\n         return productsState.value;\n     }\n\n     return productsState.where(\n         (p) =\u003e p.title.contains(productTextFilterState.value),\n     );\n}\n\n// actions\nfinal selectedProductState = RxNotifier\u003cProduct?\u003e(null);\nfinal fetchProductsState = RxNotifier(null);\n```\n\n\n\n## Reducer (RxReducer)\n\nIn this architecture you are forced to split state management\nof business rules, which may seem strange at first when seen\nthat we are always managing and reducing state in the same layer as `BLoC` and `ChangeNotifier` for example.\u003cbr\u003e\nHowever, dividing state management and business rule execution will help us distribute multiple states to the same widget, and these multiple states will not need to be concatenated beforehand through a `facade` or `proxy`.\n\nThe layer responsible for making business decisions will be called `Reducer`:\n\n```dart\nclass ProductReducer extends RxReducer {\n\n    ProductReducer(){\n        on(() =\u003e [fetchProductsState.action], _fetchProducts);\n        on(() =\u003e [selectedProductState.value], _selectProduct);\n    }\n\n    void _fetchProducts(){\n        ...\n    }\n\n    void _selectProduct(){\n        ...\n    }\n}\n```\n\n`Reducers` can register methods/functions that listen to the reactivity of an `Atom`(**RxNotifier**).\n\n## View (Widget)\n\nAny widget can listen to changes of one or many atoms,\nprovided they have the `RxRoot` widget as their ancestor.\nFor more details about RxRoot, [Read the documentation](https://github.com/Flutterando/rx_notifier/tree/master/rx_notifier).\n\nThe `context.select()` method is added via Extension to `BuildContext` and can be called on any type of Widget, `StatefulWidget` and `StatelessWidget`.\n\n```dart\n\n...\nWidget build(BuildContext context){\n     final products = context.select(\n                 () =\u003e filteredProductsState.value\n              );\n     ...\n}\n\n```\n\n## Examples\n\nFlutter projects using RxNotifier\n\n[Trivial Counter](https://github.com/Flutterando/rx_notifier/tree/master/rx_notifier/example/trivial_counter).\n\n[Shop Cart](https://github.com/Flutterando/rx_notifier/tree/master/rx_notifier/example/shop_cart).","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Frx_notifier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflutterando%2Frx_notifier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Frx_notifier/lists"}