Skip to content

Commit 0666a11

Browse files
authored
0.4.0 - Dart2 Support with Stronger Typing (#20)
* 0.4.0 - Dart2 Support with Stronger Typing
1 parent 572d9ea commit 0666a11

15 files changed

+18061
-240
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
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 beta --depth 1
12+
- git clone https://github.com/flutter/flutter.git -b master --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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
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: `new StoreProvider<AppState>`
9+
* `new StoreProvider.of(context).store` is now `StoreProvider.of<AppState>(context)`
10+
11+
## 0.3.6
12+
13+
* Add `onWillChange`. This function will be called before the builder and can be used for working with Imperative APIs, such as Navigator, TextEditingController, or TabController.
14+
315
## 0.3.6
416

517
* Add `onWillChange`. This function will be called before the builder and can be used for working with Imperative APIs, such as Navigator, TextEditingController, or TabController.

README.md

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,25 @@
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

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

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

15+
## Dart Support
16+
17+
* Dart 1: 0.3.x
18+
* Dart 2: 0.4.0+. See the migration guide below!
19+
20+
## Dart 2 Migration Guide
21+
22+
Dart 2 requires more strict typing (yay!), and gives us the option to make getting the Store from the StoreProvider more convenient!
23+
24+
1. Change `new StoreProvider(...)` to `new StoreProvider<StateClass>(...)` in your Widget tree.
25+
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 :)
26+
1527
## Examples
1628

1729
* [Simple example](https://gitlab.com/brianegan/flutter_redux/tree/master/example) - a port of the standard "Counter Button" example from Flutter
@@ -26,17 +38,19 @@ This package is built to work with [Redux.dart](https://pub.dartlang.org/package
2638

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

41+
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).
42+
2943
```dart
3044
import 'package:flutter/material.dart';
31-
import 'package:redux/redux.dart';
3245
import 'package:flutter_redux/flutter_redux.dart';
46+
import 'package:redux/redux.dart';
3347
3448
// One simple action: Increment
3549
enum Actions { Increment }
3650
3751
// The reducer, which takes the previous count and increments it in response
3852
// to an Increment action.
39-
int counterReducer(int state, action) {
53+
int counterReducer(int state, dynamic action) {
4054
if (action == Actions.Increment) {
4155
return state + 1;
4256
}
@@ -45,23 +59,29 @@ int counterReducer(int state, action) {
4559
}
4660
4761
void main() {
48-
runApp(new FlutterReduxApp());
62+
// Create your store as a final variable in a base Widget. This works better
63+
// with Hot Reload than creating it directly in the `build` function.
64+
final store = Store<int>(counterReducer, initialState: 0);
65+
66+
runApp(new FlutterReduxApp(
67+
title: 'Flutter Redux Demo',
68+
store: store,
69+
));
4970
}
5071
5172
class FlutterReduxApp extends StatelessWidget {
52-
// Create your store as a final variable in a base Widget. This works better
53-
// with Hot Reload than creating it directly in the `build` function.
54-
final store = new Store(counterReducer, initialState: 0);
73+
final Store<int> store;
74+
final String title;
75+
76+
FlutterReduxApp({Key key, this.store, this.title}) : super(key: key);
5577
5678
@override
5779
Widget build(BuildContext context) {
58-
final title = 'Flutter Redux Demo';
59-
6080
return new MaterialApp(
6181
theme: new ThemeData.dark(),
6282
title: title,
63-
home: new StoreProvider(
64-
// Pass the store to the StoreProvider. Any descendant `StoreConnector`
83+
home: new StoreProvider<int>(
84+
// Pass the store to the StoreProvider. Any ancestor `StoreConnector`
6585
// Widgets will find and use this value as the `Store`.
6686
store: store,
6787
child: new Scaffold(
@@ -90,10 +110,12 @@ class FlutterReduxApp extends StatelessWidget {
90110
// count. No need to manually manage subscriptions or Streams!
91111
new StoreConnector<int, String>(
92112
converter: (store) => store.state.toString(),
93-
builder: (context, count) => new Text(
94-
count,
95-
style: Theme.of(context).textTheme.display1,
96-
),
113+
builder: (context, count) {
114+
return new Text(
115+
count,
116+
style: Theme.of(context).textTheme.display1,
117+
);
118+
},
97119
)
98120
],
99121
),
@@ -109,21 +131,23 @@ class FlutterReduxApp extends StatelessWidget {
109131
// with no parameters. It only dispatches an Increment action.
110132
return () => store.dispatch(Actions.Increment);
111133
},
112-
builder: (context, callback) => new FloatingActionButton(
113-
// Attach the `callback` to the `onPressed` attribute
114-
onPressed: callback,
115-
tooltip: 'Increment',
116-
child: new Icon(Icons.add),
117-
),
134+
builder: (context, callback) {
135+
return new FloatingActionButton(
136+
// Attach the `callback` to the `onPressed` attribute
137+
onPressed: callback,
138+
tooltip: 'Increment',
139+
child: new Icon(Icons.add),
140+
);
141+
},
118142
),
119143
),
120144
),
121145
);
122146
}
123147
}
124-
```
148+
```
125149

126-
### Purpose
150+
## Purpose
127151

128152
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?
129153

analysis_options.yaml

Lines changed: 3 additions & 1 deletion
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
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 1 addition & 0 deletions
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)