Frontend Development 11 min read

Using Rematch for State Management in React Applications

This guide walks through creating a React Todo List app with Rematch, showing how to define typed models, initialize a Redux‑compatible store, provide it via React‑Redux, and use useSelector and typed useDispatch in components, highlighting Rematch’s concise syntax and similarity to Redux‑Toolkit.

Ximalaya Technology Team
Ximalaya Technology Team
Ximalaya Technology Team
Using Rematch for State Management in React Applications

Some readers have expressed confusion about state management when developing React Native applications. In the upcoming series we will compare several popular state‑management frameworks for both React and React Native, highlighting their usage, advantages, and drawbacks.

The previous article introduced the upgraded version of Redux, redux‑toolkit . This article focuses on a well‑known Redux enhancement library called Rematch .

Below is a complete example of building a simple Todo List app with React and Rematch. The full source code is available at the end of the article.

1. Create a new React project

npx create-react-app todolist

2. Install Rematch and react‑redux

npm install @rematch/core react-redux

3. Define the model types

import { Models } from "@rematch/core";

// Export the type that represents all models in the current business
export interface RootModel extends Models<RootModel> {
  // Currently empty
}

// Create and export the model instances
export const models: RootModel = {};

In the code above, RootModel describes the type of all models used in the application.

Rematch’s model concept is similar to a Redux‑Toolkit slice : it defines an initial state and the operations that can modify it.

4. Create a todo.ts file and define a Todo model

import { createModel } from "@rematch/core";
import { State, TODO } from "../../module/todo";
import { RootModel } from "./models";

const initState: State = {
  todos: [
    {
      text: "zsx clean room, model init data"
    }
  ]
};

export const todo = createModel<RootModel>()({
  name: 'todo',
  state: initState,
  reducers: {
    addTodo: (state: State, payload: string) => {
      return {
        ...state,
        todos: [...state.todos, { text: payload }]
      };
    },
    deleteTodo: (state: State, payload: string) => {
      const todos = state.todos.filter((item: TODO) => item.text !== payload);
      return { ...state, todos };
    }
  }
});

The Rematch model and Redux‑Toolkit slice share the same idea: they each encapsulate a piece of business state and the reducers that operate on it.

5. Add the Todo model to models.ts

import { Models } from "@rematch/core";
import { todo } from "./todo";

export interface RootModel extends Models<RootModel> {
  // The key name is used when dispatching actions
  todo: typeof todo;
}

export const models: RootModel = { todo };

Now the models object contains a todo entry, which can be accessed via store.dispatch.todo and store.getState().todo .

6. Create the store with Rematch’s init function

import { init, RematchDispatch, RematchRootState } from "@rematch/core";
import { models, RootModel } from "./model/models";

export const store = init({
  models
});

store.subscribe(() => {
  console.log('store update >>> ' + JSON.stringify(store.getState()));
});

store.dispatch.todo.addTodo("add from store");

export type Store = typeof store;
export type Dispatch = RematchDispatch<RootModel>;
export type RootState = RematchRootState<RootModel>;

The init function receives the models object and returns a Redux‑compatible store that supports subscribe and dispatch .

7. Provide the store to the React component tree

import RematchTodoApp from './rematch/RematchTodoApp';
import { store } from './rematch/store';
import { Provider } from 'react-redux';
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);

root.render(
);

8. Build the UI component and use useSelector and useDispatch

import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { TODO } from "../module/todo";
import { Dispatch, RootState } from "./store";

const RematchTodoApp = () => {
  const todos = useSelector((state: RootState) => state.todo.todos);
  const dispatch = useDispatch<Dispatch>();
  const [text, setText] = useState('');

  const handleAddTodo = () => {
    dispatch.todo.addTodo(text);
    setText('');
  };

  const handleDeleteTodo = (text: string) => {
    dispatch.todo.deleteTodo(text);
  };

  return (
This Is Rematch TODO App.
{todos && todos.map((todo: TODO, index: number) => (
{todo.text}
handleDeleteTodo(todo.text)}>finish
))}
setText(e.target.value)} />
Add Todo
);
};

export default RematchTodoApp;

In the component we use useSelector to read state.todo.todos and useDispatch (typed with Dispatch ) to dispatch actions such as dispatch.todo.addTodo and dispatch.todo.deleteTodo .

Summary

Managing state with Rematch involves the following steps:

Extend Rematch.Models to define the type of all models used in the project.

Use createModel to define a business‑specific model (e.g., a Todo model) with an initial state and reducers that must return a new state.

Initialize the store with init , passing the collection of models, and export the corresponding Store , Dispatch , and RootState types.

Wrap the application with Provider to make the store available to the component tree.

In UI components, retrieve state with useSelector and dispatch actions with a typed useDispatch .

Rematch closely mirrors Redux‑Toolkit in structure and usage, offering a more direct syntax for reducers (payload instead of action) and eliminating the need to export actions and reducers separately.

Full source code: https://github.com/shixinzhang/redux-sample/tree/main/src/rematch

typescriptReduxstate managementreactRematch
Ximalaya Technology Team
Written by

Ximalaya Technology Team

Official account of Ximalaya's technology team, sharing distilled technical experience and insights to grow together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.