restate 0.3.0 copy "restate: ^0.3.0" to clipboard
restate: ^0.3.0 copied to clipboard

A reactive state management libray for Flutter applications with no dependencies and < 200 lines.

Restate #

Restate is a reactive state management library for Flutter applications with no dependencies and < 200 lines.

Each Restate StateBloc holds a single state value accessible synchronously, as a Future or as a Stream of values.

  • StateBloc.value - Returns the current state value synchronously.
  • StateBloc.current - Returns a Future that resolves with the current value if it already has a value or otherwise waits for one to be added.
  • StateBloc.stream - Returns a Stream of updates to the state value.
  • StateBloc.changes - Returns a Stream of changes to the state value including the current and previous value.

Reading the current value #

import 'package:restate/restate.dart';

final counterState = StateBloc<int>(0);
print(counterState.value); // 0
counterState.add(1);
print(counterState.value); // 1

Listening to a Stream of values #

import 'package:restate/restate.dart';

final counterState = StateBloc<int>(0);

counterState.stream.listen((value) {
  print(value);
  // 0
  // 1
  // 2
});

counterState.add(1);
counterState.add(2);

Listening to a Stream of changes #

import 'package:restate/restate.dart';

final counterState = StateBloc<int>(0);

counterState.changes.listen((value) {
  print('${value.previous}->${value.current}');
  // null->0
  // 0->1
  // 1->2
});

counterState.add(1);
counterState.add(2);

Waiting for the current value #

import 'package:restate/restate.dart';

final counterState = StateBloc<int>();

counterState.current.then((value) => print(value)); // 1
counterState.add(1);
counterState.current.then((value) => print(value)); // 1

Accessing State in Widgets #

Accesing and listening for updates to your state is as simple as creating a StateBloc and then using a StreamBuilder to rebuild your widget when data changes:

final counterStateBloc = StateBloc<int>(0);

class MyWidget extends StatelessWidget {
  @override
  build(context) {
    return StreamBuilder(
      stream: counterStateBloc.stream,
      builder: (context, counterSnap) {
        if (!counterSnap.hasData) {
          return Text('Waiting for value...');
        }

        final counter = counterSnap.data;

        return Column(
          children: [
            Text('Counter: $counter'),
            ElevatedButton(
              onPressed: () {
                counterStateBloc.add(counter + 1);
              },
            ),
          ],
        );
      }
    )
  }
}

That's it! You can run the demo to see a more in-depth working example.

Updating a StateBloc value #

Generally, the StateBloc.add API is sufficient for updating the current value held by a StateBloc. Sometimes, however, you may be working with complex objects that need to be mutated.

To keep your state values immutable, you can see if it's possible to use a copyWith function to return new objects:

class User {
  String firstName;
  String lastName;

  User({
    required this.firstName,
    required this.lastName,
  });

  User copyWith({
    String? firstName,
    String? lastName,
  }) {
    return User(
      firstName: firstName ?? this.firstName,
      lastName: lastName ?? this.lastName,
    );
  }
}

final user = User(firstName: 'Anakin', lastName: 'Skywalker');
final userState = UserStateBloc<User>(user);

userState.add(
  userState.value.copyWith(
    firstName: 'Darth',
    lastName: 'Vader',
  ),
);

Many Flutter data objects like TextStyle already support this pattern.

If you instead need to mutate the current value, you can use the StateBloc.setValue API:

final user = User(firstName: 'Anakin', lastName: 'Skywalker');
final userState = UserStateBloc<User>(user);

userState.setValue((currentUser) {
  currentUser.firstName = 'Darth';
  currentUser.lastName = 'Vader';
});

The setValue API provides the current value held by the StateBloc, allowing you to mutate it as necessary, and then re-emits that object on the StateBloc.stream.

Feedback Welcome #

Let us know if there's a feature or changes you would like to see to Restate on GitHub and happy coding!

4
likes
160
points
53
downloads

Publisher

unverified uploader

Weekly Downloads

A reactive state management libray for Flutter applications with no dependencies and < 200 lines.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

More

Packages that depend on restate