reflux

Reflux is a state management library for React with Dart and Flutter. It provides a predictable state container with full type safety using Dart's sealed classes for exhaustive pattern matching.

Installation

dependencies:
  reflux: ^0.9.0

Core Concepts

Store

The store holds the complete state tree of your application. There should be a single store for the entire app.

import 'package:reflux/reflux.dart';

final store = createStore(counterReducer, (count: 0));

Actions

Actions are sealed classes that describe what happened. Use Dart's pattern matching on the actual TYPE, not strings.

sealed class CounterAction extends Action {}

final class Increment extends CounterAction {}
final class Decrement extends CounterAction {}
final class SetValue extends CounterAction {
  const SetValue(this.value);
  final int value;
}

Reducers

Reducers are pure functions that specify how state changes in response to actions.

typedef CounterState = ({int count});

CounterState counterReducer(CounterState state, Action action) =>
    switch (action) {
      Increment() => (count: state.count + 1),
      Decrement() => (count: state.count - 1),
      SetValue(:final value) => (count: value),
      _ => state,
    };

Quick Start

import 'package:reflux/reflux.dart';

// State as a record
typedef CounterState = ({int count});

// Actions as sealed classes
sealed class CounterAction extends Action {}
final class Increment extends CounterAction {}
final class Decrement extends CounterAction {}

// Reducer with pattern matching
CounterState counterReducer(CounterState state, Action action) =>
    switch (action) {
      Increment() => (count: state.count + 1),
      Decrement() => (count: state.count - 1),
      _ => state,
    };

void main() {
  final store = createStore(counterReducer, (count: 0));

  store.subscribe(() => print('Count: ${store.getState().count}'));

  store.dispatch(Increment()); // Count: 1
  store.dispatch(Increment()); // Count: 2
  store.dispatch(Decrement()); // Count: 1
}

Middleware

Middleware provides a third-party extension point between dispatching an action and the reducer.

Middleware<CounterState> loggerMiddleware() =>
    (api) => (next) => (action) {
          print('Dispatching: ${action.runtimeType}');
          next(action);
          print('State: ${api.getState()}');
        };

final store = createStore(
  counterReducer,
  (count: 0),
  enhancer: applyMiddleware([loggerMiddleware()]),
);

Selectors

Selectors extract and memoize derived data from the state.

final getCount = createSelector1(
  (CounterState s) => s.count,
  (count) => count * 2,
);

final doubledCount = getCount(store.getState());

Time Travel

The TimeTravelEnhancer allows you to undo/redo state changes.

final timeTravel = TimeTravelEnhancer<CounterState>();

final store = createStore(
  counterReducer,
  (count: 0),
  enhancer: timeTravel.enhancer,
);

store.dispatch(Increment());
store.dispatch(Increment());

timeTravel.undo(); // Go back one step
timeTravel.redo(); // Go forward one step

API Reference

See the full API documentation for all available functions and types.

Source Code

The source code is available on GitHub.