[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-9322":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":15,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":16,"rankGlobal":9,"rankLanguage":9,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":15,"starSnapshotCount":15,"syncStatus":29,"lastSyncTime":30,"discoverSource":31},9322,"flutter_redux","brianegan\u002Fflutter_redux","brianegan","A library that connects Widgets to a Redux Store",null,"Dart",1646,210,28,18,0,54.97,"MIT License",false,"master",true,[22,23,24,25],"dart","dartlang","flutter","redux","2026-06-12 04:00:44","# flutter_redux\n\n[![Build Status](https:\u002F\u002Ftravis-ci.org\u002Fbrianegan\u002Fflutter_redux.svg?branch=master)](https:\u002F\u002Ftravis-ci.org\u002Fbrianegan\u002Fflutter_redux)  [![codecov](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fbrianegan\u002Fflutter_redux\u002Fbranch\u002Fmaster\u002Fgraph\u002Fbadge.svg)](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fbrianegan\u002Fflutter_redux)\n\nA set of utilities that allow you to easily consume a\n[Redux](https:\u002F\u002Fpub.dartlang.org\u002Fpackages\u002Fredux) Store to build Flutter Widgets.\n\nThis package supports null-safety and is built to work with\n[Redux.dart](https:\u002F\u002Fpub.dartlang.org\u002Fpackages\u002Fredux) 5.0.0+ and Flutter 3+.\n\n## Redux Widgets \n\n  * `StoreProvider` - The base Widget. It will pass the given Redux Store to all descendants that request it.\n  * `StoreBuilder` - A descendant Widget that gets the Store from a `StoreProvider` and passes it to a Widget `builder` function.\n  * `StoreConnector` - A descendant Widget that gets the Store from the nearest `StoreProvider` ancestor, converts the `Store` into a `ViewModel` with the given `converter` function, and passes the `ViewModel` to a `builder` function. Any time the Store emits a change event, the Widget will automatically be rebuilt. No need to manage subscriptions!\n\n## Examples\n\n  * [Simple example](https:\u002F\u002Fgithub.com\u002Fbrianegan\u002Fflutter_redux\u002Ftree\u002Fmaster\u002Fexample\u002Fcounter) - a port of the standard \"Counter Button\" example from Flutter\n  * [Github Search](https:\u002F\u002Fgithub.com\u002Fbrianegan\u002Fflutter_redux\u002Ftree\u002Fmaster\u002Fexample\u002Fgithub_search) - an example of how to search as a user types, demonstrating both the Middleware and Epic approaches.\n  * [Todo app](https:\u002F\u002Fgithub.com\u002Fbrianegan\u002Fflutter_architecture_samples\u002Ftree\u002Fmaster\u002Fredux) - a more complete example, with persistence, routing, and nested state.\n  * [Timy Messenger](https:\u002F\u002Fgithub.com\u002FjanoodleFTW\u002Ftimy-messenger) - large open source app that uses flutter_redux together with Firebase Firestore.\n  \n### Companion Libraries\n  * [flipperkit_redux_middleware](https:\u002F\u002Fpub.dartlang.org\u002Fpackages\u002Fflipperkit_redux_middleware) - Redux Inspector (use [Flutter Debugger](https:\u002F\u002Fgithub.com\u002Fblankapp\u002Fflutter-debugger)) for Flutter Redux apps\n  * [flutter_redux_dev_tools](https:\u002F\u002Fpub.dartlang.org\u002Fpackages\u002Fflutter_redux_dev_tools) - Time Travel Dev Tools for Flutter Redux apps\n  * [redux_persist](https:\u002F\u002Fgithub.com\u002FCretezy\u002Fredux_persist) - Persist Redux State   \n  * [flutter_redux_navigation](https:\u002F\u002Fgithub.com\u002Fflutterings\u002Fflutter_redux_navigation) - Use redux events for navigation\n  * [flutter_redux_gen](https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=BalaDhruv.flutter-redux-gen) - VS Code Extension to generate redux code.\n \n## Usage\n\nLet's demo the basic usage with the all-time favorite: A counter example!\n\nNote: This example requires flutter_redux 0.4.0+ and Dart 2! If you're using\nDart 1, [see the old\nexample](https:\u002F\u002Fgithub.com\u002Fbrianegan\u002Fflutter_redux\u002Fblob\u002Feb4289795a5a70517686ccd1d161abdb8cc08af5\u002Fexample\u002Flib\u002Fmain.dart).\n\n```dart\nimport 'package:flutter\u002Fmaterial.dart';\nimport 'package:flutter_redux\u002Fflutter_redux.dart';\nimport 'package:redux\u002Fredux.dart';\n\n\u002F\u002F One simple action: Increment\nenum Actions { Increment }\n\n\u002F\u002F The reducer, which takes the previous count and increments it in response\n\u002F\u002F to an Increment action.\nint counterReducer(int state, dynamic action) {\n  return action == Actions.Increment ? state + 1 : state;\n}\n\nvoid main() {\n  \u002F\u002F Create your store as a final variable in the main function or inside a\n  \u002F\u002F State object. This works better with Hot Reload than creating it directly\n  \u002F\u002F in the `build` function.\n  final store = Store\u003Cint>(counterReducer, initialState: 0);\n\n  runApp(FlutterReduxApp(\n    title: 'Flutter Redux Demo',\n    store: store,\n  ));\n}\n\nclass FlutterReduxApp extends StatelessWidget {\n  final Store\u003Cint> store;\n  final String title;\n\n  FlutterReduxApp({Key key, this.store, this.title}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    \u002F\u002F The StoreProvider should wrap your MaterialApp or WidgetsApp. This will\n    \u002F\u002F ensure all routes have access to the store.\n    return StoreProvider\u003Cint>(\n      \u002F\u002F Pass the store to the StoreProvider. Any ancestor `StoreConnector`\n      \u002F\u002F Widgets will find and use this value as the `Store`.\n      store: store,\n      child: MaterialApp(\n        theme: ThemeData.dark(),\n        title: title,\n        home: Scaffold(\n          appBar: AppBar(title: Text(title)),\n          body: Center(\n            child: Column(\n              mainAxisAlignment: MainAxisAlignment.center,\n              children: [\n                \u002F\u002F Connect the Store to a Text Widget that renders the current\n                \u002F\u002F count.\n                \u002F\u002F\n                \u002F\u002F We'll wrap the Text Widget in a `StoreConnector` Widget. The\n                \u002F\u002F `StoreConnector` will find the `Store` from the nearest\n                \u002F\u002F `StoreProvider` ancestor, convert it into a String of the\n                \u002F\u002F latest count, and pass that String  to the `builder` function\n                \u002F\u002F as the `count`.\n                \u002F\u002F\n                \u002F\u002F Every time the button is tapped, an action is dispatched and\n                \u002F\u002F run through the reducer. After the reducer updates the state,\n                \u002F\u002F the Widget will be automatically rebuilt with the latest\n                \u002F\u002F count. No need to manually manage subscriptions or Streams!\n                StoreConnector\u003Cint, String>(\n                  converter: (store) => store.state.toString(),\n                  builder: (context, count) {\n                    return Text(\n                      'The button has been pushed this many times: $count',\n                      style: Theme.of(context).textTheme.display1,\n                    );\n                  },\n                )\n              ],\n            ),\n          ),\n          \u002F\u002F Connect the Store to a FloatingActionButton. In this case, we'll\n          \u002F\u002F use the Store to build a callback that will dispatch an Increment\n          \u002F\u002F Action.\n          \u002F\u002F\n          \u002F\u002F Then, we'll pass this callback to the button's `onPressed` handler.\n          floatingActionButton: StoreConnector\u003Cint, VoidCallback>(\n            converter: (store) {\n              \u002F\u002F Return a `VoidCallback`, which is a fancy name for a function\n              \u002F\u002F with no parameters and no return value. \n              \u002F\u002F It only dispatches an Increment action.\n              return () => store.dispatch(Actions.Increment);\n            },\n            builder: (context, callback) {\n              return FloatingActionButton(\n                \u002F\u002F Attach the `callback` to the `onPressed` attribute\n                onPressed: callback,\n                tooltip: 'Increment',\n                child: Icon(Icons.add),\n              );\n            },\n          ),\n        ),\n      ),\n    );\n  }\n}\n```    \n\n## Purpose\n\nOne question that [reasonable people might\nask](https:\u002F\u002Fwww.reddit.com\u002Fr\u002FFlutterDev\u002Fcomments\u002F6vscdy\u002Fa_set_of_utilities_that_allow_you_to_easily\u002Fdm3ll7d\u002F):\nWhy do you need all of this if `StatefulWidget` exists?\n\nMy advice is the same as the original Redux.JS author: If you've got a simple\napp, use the most straightforward thing possible. In Flutter, `StatefulWidget` is perfect\nfor a simple counter app.\n\nHowever, say you have the more complex app, such as an E-commerce app with a\nShopping Cart. The Shopping Cart should appear on multiple screens in your app\nand should be updated by many different types of Widgets on those different\nscreens (An \"Add Item to Cart\" Widget on all your Product Screens, \"Remove Item\nfrom Cart\" Widget on the Shopping Cart Screen, \"Change quantity\" Widgets, etc.).\n\nAdditionally, you want to test this logic, as it's the core business\nlogic to your app!\n\nNow, in this case, you could create a Testable `ShoppingCart` class as a\nSingleton or Create a Root `StatefulWidget` that passes the `ShoppingCart `*Down\nDown Down* through your widget hierarchy to the \"add to cart\" or \"remove from\ncart\" Widgets.\n\nSingletons can be problematic for testing, and Flutter doesn't have a great\nDependency Injection library (such as Dagger2) just yet, so I'd prefer to avoid\nthose.\n\n\tYet passing the ShoppingCart all over the place can get messy. It also means\nit's way harder to move that \"Add to Item\" button to a new location b\u002Fc you'd\nneed up update the Widgets throughout your app that passes the state down.\n\nFurthermore, you'd need a way to Observe when the `ShoppingCart` Changes so you\ncould rebuild your Widgets when it does (from an \"Add\" button to an \"Added\"\nbutton, as an example).\n\nOne way to handle it would be to simply `setState` every time the `ShoppingCart`\nchanges in your Root Widget, but then your whole app below the RootWidget would\nbe required to rebuild as well! Flutter is fast, but we should be thoughtful about\nwhat we ask Flutter to rebuild!\n\nTherefore, `redux` & `redux_flutter` was born for more complex stories like this\none. It gives you a set of tools that allow your Widgets to `dispatch` actions\nin a naive way, then writes the business logic in another place that will take\nthose actions and update the `ShoppingCart` in a safe, testable way.\n\nEven more, once the `ShoppingCart` has been updated in the `Store`, the `Store`\nwill emit an `onChange` event. This lets you listen to `Store` updates and\nrebuild your UI in the right places when it changes! Now, you can separate your\nbusiness logic from your UI logic in a testable, observable way, without having\nto Wire up a bunch of stuff yourself!\n\nSimilar patterns in Android are the MVP Pattern or using Rx Observables to\nmanage a View's State.\n\n`flutter_redux` handles passing your `Store` down to all of your\ndescendant `StoreConnector` Widgets. If your State emits a change event, only\nthe `StoreConnector` Widgets and their descendants will be automatically rebuilt\nwith the latest State of the `Store`!\n\nThis allows you to focus on what your app should look like and how it should\nwork without thinking about all the glue code to hook everything together!\n\n### Contributors\n\n  * [Brian Egan](https:\u002F\u002Fgithub.com\u002Fbrianegan)\n  * [Chris Bird](https:\u002F\u002Fgithub.com\u002Fchrisabird)\n","flutter_redux 是一个用于将 Flutter 小部件连接到 Redux 存储库的库。它提供了几个核心组件，如 `StoreProvider`、`StoreBuilder` 和 `StoreConnector`，这些组件使得开发者可以方便地在 Flutter 应用中使用 Redux 状态管理，并且支持空安全特性。通过 `StoreConnector`，小部件能够自动响应存储的变化而无需手动管理订阅。此项目适用于需要在 Flutter 项目中实现复杂状态管理和跨组件通信的场景，尤其适合构建具有多层嵌套状态或需要持久化存储的应用程序。",2,"2026-06-11 03:22:10","top_language"]