dva_flutter 0.1.1

  • Readme
  • Changelog
  • Installing
  • 55

dva_flutter #

Combine BloC and dva_dart together

Getting Started #

  1. Read BackGround first.
  2. Example: dva_flutter_example.

Usage #

  1. create State

state.dart:

import 'package:dva_dart/dva_dart.dart';

class CounterState implements DvaState<int> {
  final int counter;
  CounterState(this.counter);
}
  1. create model and write some effect

model.dart:

import 'package:dva_dart/dva_dart.dart';
import 'state.dart';

Future add(int p) async {
  return await p + 1;
}

Future minus(int p) async {
  return await p - 1;
}

DvaModel counterPageModel =
    DvaModel(nameSpace: 'counter', initialState: CounterState(0), reducers: {
  'updateState': (DvaState<int> state, Payload<int> payload) {
    return CounterState(payload.payload);
  },
}, effects: {
  'asyncAdd': (Payload<int> payload) async* {
    var added = await add(payload.payload);
    yield PutEffect(key: 'updateState', payload: Payload<int>(added));
  },
  'asyncMinus': (Payload<int> payload) async* {
    var minused = await minus(payload.payload);
    yield PutEffect(key: 'updateState', payload: Payload<int>(minused));
  },
});
  1. use connector to wrap up your widget

container.dart

import 'package:flutter/material.dart';
import 'package:dva_dart/dva_dart.dart';
import 'package:dva_flutter/connector.dart';
import 'state.dart';
import 'widget.dart';

Widget counterPageContainer({context}) {
  return DvaConnector(
    context: context,
    key: Key('CounterPage'),
    listenTo: ['counter'],
    builder: (BuildContext context, DvaModels models, dispatch) {
      CounterState counterState = models.getState('counter');
      return CounterPageWidget(
        title: 'Counter',
        counter: counterState.counter,
        asyncAdd: (int counter) => dispatch(
            createAction('counter/asyncAdd')(Payload(counter))),
        asyncMinus: (int counter) => dispatch(
            createAction('counter/asyncMinus')(Payload(counter))),
      );
    },
  );
}

widget.dart

import 'package:flutter/material.dart';

class CounterPageWidget extends StatelessWidget {
  final String title;
  final int counter;
  final Function asyncMinus;
  final Function asyncAdd;

  CounterPageWidget({this.title, this.counter, this.asyncMinus,this.asyncAdd});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '${this.counter}',
              style: Theme.of(context).textTheme.display1,
            ),
            IconButton(
                onPressed: () {
                    this.asyncAdd(counter);
                },
                icon: Icon(
                    Icons.thumb_up,
                    color: Colors.black,
                    size: 32.0,
                ),
            ),
            IconButton(
                onPressed: () {
                    this.asyncMinus(counter);
                },
                icon: Icon(
                    Icons.thumb_down,
                    color: Colors.black,
                    size: 32.0,
                ),
            ),
          ],
        ),
      ),
    );
  }
}

  1. put models toghther and create store
import 'package:dva_dart/dva_dart.dart';
import 'model.dart';

final DvaStore store =
    DvaStore(models: [counterPageModel]);
  1. put store in the main

import 'package:flutter/material.dart';
import 'package:dva_dart/dva_dart.dart';
import 'package:dva_flutter/provider.dart';
import 'store.dart';
import 'container.dart';


// -----

void main() {
  runApp(new MyApp(store));
}

class MyApp extends StatelessWidget {
  final DvaStore store;
  MyApp(this.store);
  @override
  Widget build(BuildContext context) {
    return DvaProvider<DvaStore>(
      child: new MaterialApp(
        initialRoute: '/',
        title: 'Streams Demo',
        theme: new ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: CounterPage(),
      ),
      store: store,
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return counterPageContainer(context: context);
  }
}


BackGround #

There are a lot of resolutions for flutter's state managing.

redux_dart and BloC are both great libs to start with.

redux_dart is mainly for react developers, but it's not easy to configure, especially when people are not javascript developers originally.

Bloc is using rxdart and using the Stream/Sink related solotions, which is recommended by Flutter official.

However, when it comes to real project development, things are getting hard.

When you are trying to make a side-effect call to server or simply trying to get states from other executions,

both Bloc and redux_dart are hard to use.

Luckily, in javascript/react world, we have DvaJS to ease the pain, which combines redux,redux_saga together, only 8 APIs to remember and easy to configure your app.

It comes to an idea that if we try using the Bloc and DvaJS together, we can use Stream/Sink and rxdart as the state listener, and use Reducer,ActionDispatcher and SideEffect as the data model configuration, things should works and may ease the pain.

For that, I make dva_dart and dva_flutter.

  • DvaProvider -- dva_flutter
  • DvaConnector -- dva_flutter
  • DvaModel -- dva_dart
  • DvaStore -- dva_dart
  • DvaEffect (PutEffect, CallEffect) -- dva_dart
  • DvaState -- dva_dart
  • Action -- dva_dart
  • Payload -- dva_dart

[0.1.1] - TODO: Add release date.

  • TODO: Describe initial release.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  dva_flutter: ^0.1.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:dva_flutter/dva_flutter.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
14
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
90
Overall:
Weighted score of the above. [more]
55
Learn more about scoring.

We analyzed this package on Dec 13, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.0
  • pana: 0.13.1+4
  • Flutter: 1.12.13+hotfix.4

Health suggestions

Fix lib/provider.dart. (-0.50 points)

Analysis of lib/provider.dart reported 1 hint:

line 24 col 39: 'ancestorWidgetOfExactType' is deprecated and shouldn't be used. Use findAncestorWidgetOfExactType instead. This feature was deprecated after v1.12.1..

Maintenance suggestions

Maintain an example. (-10 points)

Create a short demo in the example/ directory to show how to use this package.

Common filename patterns include main.dart, example.dart, and dva_flutter.dart. Packages with multiple examples should provide example/README.md.

For more information see the pub package layout conventions.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.68.0 <3.0.0
dva_dart ^0.1.1 0.1.1
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
rxdart 0.22.6 0.23.1
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test