redux-memento
TypeScript icon, indicating that this package has built-in type declarations

1.1.1 • Public • Published

Redux Memento Library

npm version

Overview

This library designed to simplify state management in Redux-toolkit applications by providing a mechanism for undo and redo functionality. The library integrates seamlessly with Redux-toolkit, allowing developers to create slices and middleware that support these time-traveling features.

Installation

Using NPM:

npm install redux-memento

or via Yarn:

yarn add redux-memento

Usage

  1. Define state and reducers types using IMementoSlice:
import { PayloadAction } from '@reduxjs/toolkit';
import { IMementoSlice } from 'redux-memento';

// Your state interface
export interface ICounter {
  value: number;
}

// Types for `createMementoSlice`:
export type CounterState = IMementoSlice<ICounter>;
export type CounterReducers = {
  increment: (state: CounterState) => void;
  decrement: (state: CounterState) => void;
  incrementByAmount: (state: CounterState, action: PayloadAction<number>) => void;
};

// Init your state as usual
const initialState: ICounter = {
  value: 0,
};
  1. Create a slice using createMementoSlice and utilize the types and interfaces you defined:
import { createMementoSlice } from 'redux-memento';

// ...

// Use the types you initialized before when creating the memento slice
// Initialize the slice as usual
export const counterSlice = createMementoSlice<ICounter, CounterReducers>({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state: CounterState) => {
      state.data.value += 1;
    },
    decrement: (state: CounterState) => {
      state.data.value -= 1;
    },
    incrementByAmount: (state: CounterState, action: PayloadAction<number>) => {
      state.data.value += action.payload;
    },
  },
});

export const { increment, decrement, incrementByAmount, redo, undo, setHistory } = counterSlice.actions;

export default counterSlice.reducer;
  1. Create a middleware using mementoMiddleware and apply it in the store. Specify the slice name, setHistory action, and actions to track state changes:
import { Store, configureStore } from '@reduxjs/toolkit';
import CounterReducer, { decrement, increment, setHistory } from '../features/counter/counterSlice';
import { mementoMiddleware } from 'redux-memento';

export const store: Store = configureStore({
  reducer: {
    counter: CounterReducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().prepend(mementoMiddleware('counter', setHistory, [increment, decrement]).middleware),
});
  1. Now, easily travel history with redo and undo:
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { increment, decrement, undo, redo } from '../features/counter/counterSlice';

export default function CounterMementoSlice() {
  const count = useSelector(({ counter }) => counter.data);
  const dispatch = useDispatch();

  const increaseCount = () => {
    dispatch(increment());
  };

  const decreaseCount = () => {
    dispatch(decrement());
  };

  const undoCounter = () => {
    dispatch(undo());
  };

  const redoCounter = () => {
    dispatch(redo());
  };

  return (
    <div>
      <h2>Counter: {count.value}</h2>
      <p>Using Memento Slice</p>
      <button onClick={increaseCount}>Increase</button>
      <button onClick={decreaseCount}>Decrease</button>
      <button onClick={undoCounter}>Undo</button>
      <button onClick={redoCounter}>Redo</button>
    </div>
  );
}

You can see the full example in the example folder.

How it works

You can read the read the story I went trough in this article.

Contributing

We welcome contributions! Before you start, please take a moment to review the installation guideline. After you finished your development, just make a PR.

Installation

  1. Clone the repository and make a fork:
git clone https://github.com/tomerbabila/redux-memento.git
  1. Create a new branch for your feature or bug fix:
git checkout -b feature/your-feature-name
  1. Install project dependencies:
npm ci
  1. If you wish to run the example app, run this command before:
npm link ../node_modules/react

This step is according to the first answer in this stackoverflow.

  1. Before pushing, make sure that everything is OK using these commands:
npm run prepare
npm run prepublishOnly

Package Sidebar

Install

npm i redux-memento

Weekly Downloads

11

Version

1.1.1

License

MIT

Unpacked Size

18.9 kB

Total Files

33

Last publish

Collaborators

  • tomerbabila