This package will make your redux store undoable.
- Support for making only a slice of the state undoable
- more examples and documentation
define the dependency in your pubspec.yaml file:
dependencies:
redux_undo: ^1.0.0+1update your applications packages by running
pub getor when using flutter as a framework
flutter pub getimport the package to use in the file you are setting up redux:
import 'package:redux_undo/redux_undo.dart';redux_undo will slightly modify your state by adding a new properties-layer at the root of the store. The final structure will look like this:
/// when accessed directly from the store, store.state will have this structure
UndoableHistory<S> state = {
past: <S>[],
present: null, // <-- the current state of the app
future: <S>[],
latestUnfiltered: null // <-- basically equals present, to store a mutual state before storing it into past or future
};Because it modifies the initial state you need to initiate redux_undo when initiating the redux store.
This is done by calling 2 separate functions:
/// to wrap the root reducer
Reducer<UndoableState<S>> createUndoableReducer<S>(Reducer<S> reducer, { UndoableConfig config });
/// to wrap the Root state of your app.
UndoableState<S> createUndoableState<S>(S initialState, bool ignoreInitialState);Here is an example of how this can be done in a flutter app:
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';
import 'package:redux_undo/redux_undo.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final Store<UndoableState<RootState>> store = Store<UndoableState<RootState>>(
createUndoableReducer<RootState>(rootReducer),
initialState: createUndoableState(RootState.initial(), false),
);
@override
Widget build(BuildContext context) {
return StoreProvider<UndoableState<RootState>>(
store: store,
child: MaterialApp(
title: 'Redux Undo Demo',
home: const MyHomePage(),
),
);
}
}redux_undo provides 4 basic actions
-
UndoableUndoAction- Standard-Action for undoUsage:
store.dispatch(UndoableUndoAction()) -
UndoableRedoAction- Standard-Action for redoUsage:
store.dispatch(UndoableRedoAction()) -
UndoableJumpAction- Standard-Action for jump (to past or to future)Usage:
store.dispatch(UndoableJumpAction(index: -2))// <- jumps 2 steps to the past (same as dispatchingUndoableUndoActiontwice)Usage:
store.dispatch(UndoableJumpAction(index: 0))// <- does nothing, since it just returns the currentUndoableStateUsage:
store.dispatch(UndoableJumpAction(index: 2))// <- jumps 2 steps to the future (same as dispatchingUndoableRedoActiontwice) -
UndoableClearHistoryAction- Standard-Action for clearing the history
It is possible to provide a configuration object to the UndoableState instantiation like this:
final UndoableConfig config = UndoableConfig(
limit: 100,
blackList: <Type>[
BlacklistedAction,
],
whiteList: <Type>[
WhitelistedAction,
],
);Then pass it to the createUndoableReducer function like this:
final Store<UndoableState<RootState>> store = Store<UndoableState<RootState>>(
createUndoableReducer<RootState>(rootReducer, config: config),
initialState: createUndoableState(RootState.initial(), false),
);These are the options the UndoableConfig class provides:
- int limit: limits the length of the
UndoableState.pastList and with this ultimately the length ofUndoableState.futureas well- default value => 10
- List whiteList: actions in this list need to be extended from one of the provided
redux_undoactions and will fire the originalrootReducerafter performing the action they extended from without updatingUndoableState.pastorUndoableState.future