ilokesto

Reducer

Using reducers for complex state transitions in @ilokesto/state.

Reducer

For complex state transitions, @ilokesto/state supports a reducer-based mode similar to React's useReducer or Redux.

Defining a Reducer

A reducer is a pure function that takes the current state and an action, and returns the next state.

import { create } from '@ilokesto/state';

type State = { count: number };
type Action = { type: 'increment' } | { type: 'decrement' } | { type: 'set'; value: number };

const counterReducer = (state: State, action: Action): State => {
  switch (action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'decrement': return { count: state.count - 1 };
    case 'set': return { count: action.value };
    default: return state;
  }
};

const useCounter = create(counterReducer, { count: 0 });

Dispatching Actions

In reducer mode, the hook returns a dispatch function instead of setState.

function Counter() {
  const [count, dispatch] = useCounter(state => state.count);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
    </div>
  );
}

Global Dispatch

You can also use the writeOnly accessor to get the dispatch function outside of React.

export const incrementCount = () => {
  const dispatch = useCounter.writeOnly();
  dispatch({ type: 'increment' });
};

Why Use Reducers?

  • Complex Logic: When state transitions depend on multiple fields or require complex validation.
  • Traceability: Reducers provide a clear path for all state changes, which is especially useful when combined with the logger or devtools middleware.
  • Interoperability: Easier to migrate existing useReducer logic to a global store.

Important Note

  • No Partial Updates: Reducers must always return the full state object. Partial state updates are not supported in reducer mode.
  • Middleware Integration: Reducer-based stores fully support all @ilokesto/state middleware.

On this page