Using middlewares
Middlewares are functions that can be used to extend the functionality of the store. They can be used to add additional functionality to the store, such as logging, error handling, or async operations.
Using middlewares with the store
To use middlewares with the store, you need to pass them as an array to the relevant middlewares
option when creating the store.
import { Store } from "@genshi/core";
import { myActionMiddleware } from "./my-action-middleware";import { myEffectMiddleware } from "./my-effect-middleware";
const store = new Store( { count: 0 },
{ middlewares: { actions: [myActionMiddleware], effects: [myEffectMiddleware], }, },);
Official middlewares
Genshi provides only one official middleware - Immer.
Immer
Immer is a powerful library that lets you write immutable updates to the state in a mutable way.
To use Immer with Genshi, you need to pass the middleware to the middlewares
option when creating the store. To get started with Immer:
-
First, install the middlewares package
npm install @genshi/middlewaresyarn add @genshi/middlewarespnpm install @genshi/middlewares -
Pass the Immer middleware to the store
import { Store } from "@genshi/core";import { immer } from "@genshi/middlewares/immer";const store = new Store({ count: 0 },{middlewares: {actions: [immer],},},); -
You can now update the state in a mutable way
store.action("increment", (state) => {return {count: state.count + 1,};state.count += 1;});
Custom middlewares
Genshi allows you to use both create and use both action and effect middlewares.
Custom action middleware
To create a custom action middleware, you can use the ActionMiddleware
type from the core package.
export const myActionMiddleware: ActionMiddleware = ({ state, handler, payload,}) => { Logger.log("Action started", { state, payload }); return state;};
Applying the action while passing through a middleware
A common use case is to apply the action while passing through a middleware. This can be done by calling the handler
function with the state and payload. This is how the Immer middleware works!
export const myActionMiddleware: ActionMiddleware = ({ state, handler, payload,}) => { Logger.log("Action started", { state, payload });
const newState = handler({ state, payload }); Logger.log("Action ended", { state: newState, payload });
return newState;};
Custom effect middleware
To create a custom effect middleware, you can use the EffectMiddleware
type from the core package.
export const myEffectMiddleware: EffectMiddleware = ({ state, handler, payload, dispatch,}) => { Logger.log("Action started", { state, payload });};
Applying the effect while passing through a middleware
Similar to actions, a common use case is to apply the effect while passing through a middleware. This can be done by calling the handler
function with the state, payload, and dispatch function.
export const myEffectMiddleware: EffectMiddleware = ({ state, handler, payload, dispatch,}) => { Logger.log("Effect started", { state, payload });
handler({ state, payload, dispatch }); Logger.log("Effect ended", { state, payload });};