---
sidebar_position: 4
title: Derived State
---

# Derived State

In some scenarios, components need to perform further calculations on the State in Model before they can be used in the components. This logic can be directly written in the component or implemented through derived states in Model. Derived states are defined under the `computed` field in the Model. Depending on the dependencies of the Model and the return type, there are three ways to define derived states.

## Only Depend on the Model's Own State

The derived state only depends on the current Model's State, which is passed as the first parameter to the derived state's definition function.

For example, the todo application has `items` and `filter` in its State, and `filter` is used to filter the todo items displayed on the current page. Therefore, we define a `visibleTodos` derived state that can be directly used in the component. The sample code is as follows:

```ts
/**
 *  Assuming the structure of the todo item is as follows:
{
    id: string;          // id
    text: string;        // todo
    completed: boolean;
}
**/

const todoModel = model('todo').define({
  state: {
    items: [],
    filter: 'ALL', // ALL: show all；COMPLETED: show completed；ACTIVE: show active
  },
  computed: {
    visibleTodos: state => {
      switch (state.filter) {
        case 'ALL':
          return state.items;
        case 'COMPLETED':
          return todos.filter(t => t.completed);
        case 'ACTIVE':
          return todos.filter(t => !t.completed);
        default:
          return [];
      }
    },
  },
});
```

Derived state will eventually be merged with the Model's State, so the derived state can be accessed through the Model's State object. For example, the `visibleTodos` can be used in the component as follows:

```ts
function Todo() {
  const [state, actions] = useModel(todoModel);

  return (
    <div>
      <div>
        {state.visibleTodos.map(item => (
          <div key={item.id}>{item.text}</div>
        ))}
      </div>
    </div>
  );
}
```

## Dependent State from Other Models

In addition to depending on the current model's state, derived states may also depend on the state of other models. In this case, the definition format for the derived state is:


```ts
[stateKey]: [...depModels, (selfState, ...depModels) => computedState]
```

The following example demonstrates how the derived state `combinedValue` of `barModel` depends on the state of `fooModel`.


```ts
const fooModel = model('foo').define({
  state: {
    value: 'foo',
  },
});

const barModel = model('bar').define({
  state: {
    value: 'foo',
  },
  computed: {
    combinedValue: [
      fooModel,
      (state, fooState) => state.value + fooState.value,
    ],
  },
});
```

## Derived State with Function Type

Derived states can also return a function. In this case, the definition format for the derived state is:

```ts
[stateKey]: (state) => (...args) => computedState    // Only relies on its own state
[stateKey]: [...depModels, (selfState, ...depModels) => (...args) => computedState]  // Relies on the state of other models
```

Assuming the `filter` state is not stored in the state of the todo app, but is instead used directly in the component, `visibleTodos` can be a function type value. This function receives the `filter` parameter when used in the component, as shown below:


```ts
const todoModel = model('todo').define({
  state: {
    items: [],
  },
  computed: {
    visibleTodos: state => filter => {
      switch (filter) {
        case 'ALL':
          return state.items;
        case 'COMPLETED':
          return todos.filter(t => t.completed);
        case 'ACTIVE':
          return todos.filter(t => !t.completed);
        default:
          return [];
      }
    },
  },
});

function Todo(props) {
  // use props pass filter
  const { filter } = props;
  const [state, actions] = useModel(todoModel);

  // get final todos
  const todos = state.visibleTodos(filter);

  return (
    <div>
      <div>
        {todos.map(item => (
          <div key={item.id}>{item.text}</div>
        ))}
      </div>
    </div>
  );
}
```

:::info Additional Reference
[Using Models](/guides/topic-detail/model/computed-state)
:::
