---
sidebar_position: 1
title: Quick Start
---
# Quick Start

import ReduckMigration from "@site-docs/components/reduck-migration"

<ReduckMigration />

[Reduck](https://github.com/web-infra-dev/reduck) is a state management library developed by the Modern.js team that follows the MVC pattern. Its underlying state storage is based on [Redux](https://redux.js.org/) implementation, while providing a higher level of abstraction and full compatibility with the Redux ecosystem.

The goal of Reduck is to organize the development structure of React applications in the MVC pattern, maintain business logic in the Model layer, decoupling business logic from UI, making it easier for developers to focus on business logic, and reducing duplicated work (boilerplate code) through higher level of abstraction.

In the MVC pattern, Reduck plays the role of M(Model), React UI Component corresponds to V(View), and gets the Model from Reduck and modifies the Model's React Container Component, which corresponds to C(View Controller/Container).

The state management solution of Modern.js is implemented through built-in Reduck. Using Reduck in Modern.js not only eliminates the manual integration process, but also allows all Reduck APIs to be imported and used directly from the Modern.js Runtime package, providing a better consistency experience.

:::info
1. To use Reduck APIs in Modern.js, you need to set [runtime.state](/configure/app/runtime/state) to enable the state management plugin.
2. Reduck can also be used separately as a state management library [outside of Modern.js](/guides/topic-detail/model/use-out-of-modernjs).

:::

## Core Concepts

There are only four core concepts in Reduck: Model, State, Actions, and Effects.

Model: Encapsulates the logic and required state of an independent module, consisting of State, Actions, and Effects.

State: The state stored in the Model.

Actions: Pure functions used to modify State, functions must be **Synchronous**.

Effects: Functions with side effects used to modify State, functions can be **Asynchronous**. Effects can call their own Actions and Effects or those of other Models.

The Reduck data flow is shown in the following figure:

![Reduck Data Flow](https://lf3-static.bytednsdoc.com/obj/eden-cn/zq-uylkvT/ljhwZthlaukjlkulzlp/reduck-concept.svg)

## Basic Usage

Next, let's take a simple **Counter** application as an example to demonstrate the basic usage of Reduck.

First, we define a Model named `count`:

```js
import { model } from '@modern-js/runtime/model';

const countModel = model('count').define({
  state: {
    value: 1,
  },
});

export default countModel;
```

We use the API `model` to create `countModel`, which currently only contains the state that stores the counter `value`, that is, value in the code.

We define an action to increase the counter by 1:

```js
import { model } from '@modern-js/runtime/model';

const countModel = model('count').define({
  state: {
    value: 1,
  },
  actions: {
    add(state) {
      state.value += 1;
    },
  },
});

export default countModel;
```

In the `add` action, we can directly modify the value of the state and perform the increment operation without treating the state as an immutable object. This is because Reduck integrates [immer](https://github.com/immerjs/immer), which can directly modify the original state object.

Next, we will demonstrate how to use the Model in a component.

Create a new component called `Counter`, and use the `countModel` via the `useModel` API inside the component:

```js
import { useModel } from '@modern-js/runtime/model';
import countModel from './models/count';

function Counter() {
  const [state, actions] = useModel(countModel);

  return (
    <div>
      <div>counter: {state.value}</div>
      <button onClick={() => actions.add()}>add</button>
    </div>
  );
}
```

`useModel` gets the `state` and `actions` of `countModel`. The component displays the current value of the counter, and clicking the `add` button increments the counter by 1.

:::info
Due to the simplicity of the example used here, the layering of the MVC pattern is not strictly followed. The `Counter` component acts as both the V and C layers.

:::

The final demonstration effect is as follows:

![countModel](https://lf3-static.bytednsdoc.com/obj/eden-cn/eueh7vhojuh/modern/simple-count-model.gif)

That completes a simple counter application. You can view the complete example code for this section [here](https://github.com/web-infra-dev/modern-js-examples/tree/main/series/tutorials/runtime-api/model/counter-model).

