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

2.0.1 • Public • Published

reduceur 🥖

Sophisticated reducers


npm version Size GitHub license

reduceur makes it hassle-free to create type-safe state reducers. No unweildy switch-statements and TypeScript boilerplate. Just define your event handlers and you're ready!

Additionally, reduceur comes with Immer's produce API baked in, allowing you to write even more compact event handlers.

  • 🥖 Simple
  • 🥖 Great TS support
  • 🥖 Uses Immer
  • 🥖 Framework agnostic
  • 🥖 Inspired by XState's createModel and Redux Toolkit's createSlice APIs

Quick Start

npm i reduceur immer
import { createReducer, State } from "reduceur";

type CounterState = {
  count: number;
};

const counterReducer = createReducer((state: State<CounterState>) => ({
  incremented: () => {
    state.count++;
  },
  decremented: () => {
    state.count--;
  },
  changed: (payload: { count: number }) => {
    state.count = payload.count;
  },
}));

const initialState = { count: 0 };
const nextState = counterReducer(initialState, { type: "changed", count: 999 });

Event Creators

The reducer returned from createReducer comes with built-in event creators:

import { createReducer, State } from "reduceur";

type CounterState = {
  count: number;
};

const counterReducer = createReducer((state: State<CounterState>) => ({
  changed: (payload: { newCount: number }) => (state.count = payload.newCount),
}));

const initialState = { count: 0 };

const nextState = counterReducer(
  initialState,
  // event names are prefixed with `create`
  counterReducer.createChanged({ newCount: 1000 })
);

Note that these are event creators, which means that invoking them only returns a compatible event object; it does not send any events to the reducer.

connect

A connect method is available on the returned reducer, which, by providing a function with which events can be sent to your store, allows you to create an object with event senders.

A contrived example with React's useReducer:

import { createReducer, State } from "reduceur";

const counterReducer = createReducer((state: State<CounterState>) => ({
  incremented: () => state.count++,
  changed: (payload: { newCount: number }) => (state.count = payload.newCount),
}));

const Counter = () => {
  const [state, send] = useReducer(counterReducer, { count: 0 });

  // event names are prefixed with `send`
  const { sendIncremented, sendChanged } = counterReducer.connect(send);

  return (
    <>
      <button onClick={sendIncremented}>Increment</button>
      <button onClick={() => sendChanged({ newCount: 100 })}>Set to 100</button>
    </>
  );
};

Readme

Keywords

none

Package Sidebar

Install

npm i reduceur

Weekly Downloads

1

Version

2.0.1

License

none

Unpacked Size

12 kB

Total Files

6

Last publish

Collaborators

  • janove