> Markdown version of [State Management](https://vaadin.com/docs/next/hilla/lit/guides/state-management). Section index: [llms.txt](https://vaadin.com/docs/next/hilla/llms.txt)

# State Management with MobX

Application state can be managed in many different ways. In simple applications, you may not need an explicit state management strategy. However, your application may grow to have many views or a complex UI where the same data needs to be displayed in multiple places, or where there are many dependencies between UI controls. In such situations, it may become difficult to keep the application in a consistent state when the user interacts with it. If you don’t have a good state management strategy, it can be easy to introduce new bugs when changing application logic.

This is where a state management library such as [MobX](https://mobx.js.org/) can help to make the application easier to maintain and extend. Here, we focus on an approach to store all shared frontend state in a central MobX state store that acts as the single source of truth for the application state. It’s then easy to display the state data, or anything derived from it, anywhere in the UI, so that the data is automatically updated everywhere it’s displayed whenever the data is updated in the state store.

## <a id="using-mobx-in-your-application"></a>Using MobX in your Application

Hilla recommends using the [MobX](https://mobx.js.org/) library to manage frontend state in your applications. When using Lit, you need to extend the `MobxLitElement` class, instead of `LitElement`. When your views are based on `MobxLitElement`, any MobX observables used in the `render()` method are automatically tracked so that any change to those observables is automatically reflected in the view.

The Hilla Lit starter applications take care of setting up the basics for you by providing a MobX store (named `AppState`) and `View` and `Layout` helper base classes for your application views and layouts. Both `View` and `Layout` extend `MobxLitElement` and you can expand the `AppState` store with your own observables and actions to be used in your views.

> **Caution: MobX decorators with TypeScript**
>
> MobX has experimental support for decorators (`@observable`, `@action`) but using them requires a special setting `"useDefineForClassFields": true` in `tsconfig.json`. Using this setting [breaks Lit decorators](https://github.com/lit/lit-element/issues/855) (`@property`, `@query`), so you cannot use both Lit decorators and MobX decorators in the same app. For now, we recommend not using MobX decorators in projects that use Lit.
>
> For more information, see [Enabling decorators](https://mobx.js.org/enabling-decorators.html#enabling-decorators-) in the MobX documentation.

## <a id="creating-a-data-store"></a>Creating a Data Store

Here is a minimal example of a MobX store that contains one [observable](https://mobx.js.org/observable-state.html) property (`quote`) and one [action](https://mobx.js.org/actions.html) (`setQuote()`) to update that property. Here, the store is initialized and exported on the last line, so that you can import the same store instance into any view or component to access the shared state.

`my-state.ts`

```typescript
import { makeAutoObservable } from 'mobx';

class MyState {
  quote: string = `Anything that can be derived from the application state,
    should be. Automatically. - MobX documentation`;

  constructor() {
    makeAutoObservable(this);
  }

  setQuote(quote: string) {
    this.quote = quote;
  }
}
export const myState = new MyState();
```

[makeAutoObservable](https://mobx.js.org/observable-state.html#makeautoobservable) can automatically infer that `quote` is an observable and `setQuote()` is an action.

Make sure that an initial value is assigned to all state properties before calling `makeAutoObservable()`, otherwise the property will not be observable. This is a [MobX limitation](https://mobx.js.org/observable-state.html#limitations), since we cannot use the TypeScript configuration `"useDefineForClassFields": true` due to the conflict with Lit decorators mentioned earlier.

> **Note: Data Store Definition**
>
> "The main responsibility of stores is to move logic and state out of your components into a standalone testable unit." – [Defining data stores](https://mobx.js.org/defining-data-stores.html#stores) in MobX documentation.

## <a id="using-a-store"></a>Using a Store

`my-view.ts`

```typescript
import { html } from 'lit';
import { customElement } from 'lit/decorators.js';
import '@vaadin/text-field';
import type { TextField } from '@vaadin/text-field';
import { MobxLitElement } from '@adobe/lit-mobx';
import { myState } from 'Frontend/store/my-state'; // (1)

@customElement('my-view')
export class MyView extends MobxLitElement { // (2)
  render() {
    const { quote } = myState; // (3)

    // (4)
    return html`
      <p>${quote}</p>
      <vaadin-text-field .value="${quote}" @input="${this.onInput}"></vaadin-text-field>
    `;
  }

  onInput(e: InputEvent) {
    myState.setQuote((e.target as TextField).value); // (5)
  }
}
```

1. Import the store into your view or component.

2. Make sure that the view or component extends `View`.

3. Alias one or more state properties from `myState` into local variables for easy referencing.

4. Use state properties in the template.

5. Update state by calling an action method in the store.

By default, the state cannot be changed outside of actions. Read more about [actions](https://mobx.js.org/actions.html) in the MobX documentation.

## <a id="understanding-mobx"></a>Understanding MobX

For information on using MobX effectively and understanding how it works, you should take a look at the official [MobX documentation](https://mobx.js.org/), which is a great resource for learning the basic concepts, as well as advanced usage.

In addition to the concepts of observables and actions that we’ve demonstrated here, you should also be aware of [computed](https://mobx.js.org/computeds.html) values and [reactions](https://mobx.js.org/reactions.html) and when to use them.

## <a id="external-links-references"></a>External Links & References

- [MobX documentation](https://mobx.js.org/)

- MobxLitElement from [`lit-mobx`](https://github.com/adobe/lit-mobx)

- Hilla Tips video: [LitElement state management with MobX](https://www.youtube.com/watch?v=MNxnZ8pzSBo)

- Example project referenced in the aforementioned video: <https://github.com/marcushellberg/vaadin-fusion-mobx>
