Skip to content

Commit 5f3c6ac

Browse files
committed
0.4.0 - Dart2 Support with Stronger Typing
1 parent 500d0fe commit 5f3c6ac

14 files changed

+18047
-202
lines changed

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ addons:
99
- libstdc++6
1010
- fonts-droid
1111
before_script:
12-
- git clone https://github.com/flutter/flutter.git -b alpha --depth 1
12+
- git clone https://github.com/flutter/flutter.git -b beta --depth 1
1313
- ./flutter/bin/flutter doctor
1414
script:
15-
- ./flutter/bin/flutter test --coverage --coverage-path=lcov.info
15+
- ./flutter/bin/flutter test --preview-dart-2 --coverage --coverage-path=lcov.info
1616
after_success:
1717
- bash <(curl -s https://codecov.io/bash)
1818
cache:

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 0.4.0
4+
5+
* Works with Dart 2 (no longer supports Dart 1)
6+
* Stronger Type info Required
7+
* Breaking Changes:
8+
* `StoreProvider` now requires generic type info: `StoreProvider<AppState>`
9+
* `new StoreProvider.of(context).store` is now `StoreProvider.of<AppState>(context)`
10+
311
## 0.3.5
412

513
* Bugfix: `onInit` was not called before the initial ViewModel is constructed.

README.md

+46-25
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,41 @@
44

55
A set of utilities that allow you to easily consume a [Redux](https://pub.dartlang.org/packages/redux) Store to build Flutter Widgets.
66

7-
This package is built to work with [Redux.dart](https://pub.dartlang.org/packages/redux).
7+
This package is built to work with [Redux.dart](https://pub.dartlang.org/packages/redux).
8+
89
## Redux Widgets
910

1011
* `StoreProvider` - The base Widget. It will pass the given Redux Store to all descendants that request it.
1112
* `StoreBuilder` - A descendant Widget that gets the Store from a `StoreProvider` and passes it to a Widget `builder` function.
1213
* `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!
1314

15+
## Dart Support
16+
17+
* Dart 1: 0.3.x
18+
* Dart 2: 0.4.0+. See the migration guide below!
19+
1420
## Examples
1521

1622
* [Simple example](https://gitlab.com/brianegan/flutter_redux/tree/master/example) - a port of the standard "Counter Button" example from Flutter
17-
* [Todo app](https://gitlab.com/brianegan/flutter_architecture_samples/tree/master/example/redux) - a more complete example, with persistence, routing, and nested state.
18-
23+
* [Todo app](https://gitlab.com/brianegan/flutter_architecture_samples/tree/master/example/redux) - a more complete example, with persistence, routing, and nested state.
24+
1925
## Usage
2026

2127
Let's demo the basic usage with the all-time favorite: A counter example!
2228

29+
Note: This example requires flutter_redux 0.4.0+ and Dart 2! If you're using Dart 1, [see the old example](https://github.com/brianegan/flutter_redux/blob/eb4289795a5a70517686ccd1d161abdb8cc08af5/example/lib/main.dart).
30+
2331
```dart
2432
import 'package:flutter/material.dart';
25-
import 'package:redux/redux.dart';
2633
import 'package:flutter_redux/flutter_redux.dart';
34+
import 'package:redux/redux.dart';
2735
2836
// One simple action: Increment
2937
enum Actions { Increment }
3038
3139
// The reducer, which takes the previous count and increments it in response
3240
// to an Increment action.
33-
int counterReducer(int state, action) {
41+
int counterReducer(int state, dynamic action) {
3442
if (action == Actions.Increment) {
3543
return state + 1;
3644
}
@@ -39,34 +47,40 @@ int counterReducer(int state, action) {
3947
}
4048
4149
void main() {
42-
runApp(new FlutterReduxApp());
50+
// Create your store as a final variable in a base Widget. This works better
51+
// with Hot Reload than creating it directly in the `build` function.
52+
final store = Store<int>(counterReducer, initialState: 0);
53+
54+
runApp(FlutterReduxApp(
55+
title: 'Flutter Redux Demo',
56+
store: store,
57+
));
4358
}
4459
4560
class FlutterReduxApp extends StatelessWidget {
46-
// Create your store as a final variable in a base Widget. This works better
47-
// with Hot Reload than creating it directly in the `build` function.
48-
final store = new Store(counterReducer, initialState: 0);
61+
final Store<int> store;
62+
final String title;
63+
64+
FlutterReduxApp({Key key, this.store, this.title}) : super(key: key);
4965
5066
@override
5167
Widget build(BuildContext context) {
52-
final title = 'Flutter Redux Demo';
53-
54-
return new MaterialApp(
55-
theme: new ThemeData.dark(),
68+
return MaterialApp(
69+
theme: ThemeData.dark(),
5670
title: title,
57-
home: new StoreProvider(
58-
// Pass the store to the StoreProvider. Any descendant `StoreConnector`
71+
home: StoreProvider<int>(
72+
// Pass the store to the StoreProvider. Any ancestor `StoreConnector`
5973
// Widgets will find and use this value as the `Store`.
6074
store: store,
61-
child: new Scaffold(
62-
appBar: new AppBar(
63-
title: new Text(title),
75+
child: Scaffold(
76+
appBar: AppBar(
77+
title: Text(title),
6478
),
65-
body: new Center(
66-
child: new Column(
79+
body: Center(
80+
child: Column(
6781
mainAxisAlignment: MainAxisAlignment.center,
6882
children: [
69-
new Text(
83+
Text(
7084
'You have pushed the button this many times:',
7185
),
7286
// Connect the Store to a Text Widget that renders the current
@@ -84,7 +98,7 @@ class FlutterReduxApp extends StatelessWidget {
8498
// count. No need to manually manage subscriptions or Streams!
8599
new StoreConnector<int, String>(
86100
converter: (store) => store.state.toString(),
87-
builder: (context, count) => new Text(
101+
builder: (context, count) => Text(
88102
count,
89103
style: Theme.of(context).textTheme.display1,
90104
),
@@ -103,11 +117,11 @@ class FlutterReduxApp extends StatelessWidget {
103117
// with no parameters. It only dispatches an Increment action.
104118
return () => store.dispatch(Actions.Increment);
105119
},
106-
builder: (context, callback) => new FloatingActionButton(
120+
builder: (context, callback) => FloatingActionButton(
107121
// Attach the `callback` to the `onPressed` attribute
108122
onPressed: callback,
109123
tooltip: 'Increment',
110-
child: new Icon(Icons.add),
124+
child: Icon(Icons.add),
111125
),
112126
),
113127
),
@@ -117,7 +131,14 @@ class FlutterReduxApp extends StatelessWidget {
117131
}
118132
```
119133

120-
### Purpose
134+
## Dart 2 Migration
135+
136+
Dart 2 requires more strict typing (yay!), and gives us the option to make getting the Store from the StoreProvider more convenient!
137+
138+
1. Change `new StoreProvider(...)` to `StoreProvider<StateClass>(...)` in your Widget tree.
139+
2. Change `new StoreProvider.of(context).store` to `StoreProvider.of<StateClass>(context)` if you're directly fetching the `Store<AppState>` yourself from the `StoreProvider<AppState>`. No need to access the `store` field directly any more since Dart 2 can now infer the proper type with a static function :)
140+
141+
## Purpose
121142

122143
One question that [reasonable people might ask](https://www.reddit.com/r/FlutterDev/comments/6vscdy/a_set_of_utilities_that_allow_you_to_easily/dm3ll7d/): Why do you need all of this if `StatefulWidget` exists?
123144

analysis_options.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
analyzer:
2-
strong-mode: true
2+
strong-mode:
3+
implicit-casts: false
4+
implicit-dynamic: false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"fonts":[{"asset":"fonts/MaterialIcons-Regular.ttf"}],"family":"MaterialIcons"}]

0 commit comments

Comments
 (0)