# MobX State Management-Simple and Powerful State Machine

MobX is a library for building responsive data models, offering a declarative approach to state management that automatically updates dependent views when data changes.

## Creating Observable State

MobX uses the `@observable` decorator to create observable objects, arrays, or primitive types. When these change, observers depending on them are automatically updated.

```javascript
import { observable } from 'mobx';

class Todo {
  @observable title;
  @observable completed;

  constructor(title) {
    this.title = title;
    this.completed = false;
  }
}

const todo1 = new Todo("Learn MobX");
```

## Responsive Computed Values

The `@computed` decorator creates computed values based on other observables, automatically updating when dependencies change.

```javascript
class TodoList {
  @observable todos = [];
  @computed get completedCount() {
    return this.todos.filter(todo => todo.completed).length;
  }
}

const todoList = new TodoList();
todoList.todos.push(todo1);
```

## Actions

The `@action` decorator ensures state changes occur in a controlled environment, preventing unintended modifications.

```javascript
class TodoList {
  // ...
  @action addTodo(title) {
    this.todos.push(new Todo(title));
  }

  @action toggleTodo(index) {
    this.todos[index].completed = !this.todos[index].completed;
  }
}
```

## Observers

In React, use the `mobx-react` library’s `observer` higher-order component or `useObserver` hook to make components reactive to state changes.

```jsx
import React from 'react';
import { observer } from 'mobx-react-lite';

const TodoListComponent = observer(({ todoList }) => (
  <ul>
    {todoList.todos.map((todo, index) => (
      <li key={index}>
        {todo.title} - {todo.completed ? 'Completed' : 'Not completed'}
      </li>
    ))}
  </ul>
));

const App = () => {
  const todoList = new TodoList();
  return <TodoListComponent todoList={todoList} />;
};
```

## Reactive Programming

MobX’s core is its reactive system, where data changes automatically propagate to dependent computed values and observers without manual `setState` calls. Reactive programming emphasizes data flow and change propagation, enabling programs to respond to data changes automatically.

### Observables

MobX uses the `@observable` decorator or `observable` function to create observable values. When these change, any dependent computations or views update automatically.

```javascript
import { observable } from 'mobx';

class Counter {
  @observable count = 0;
}

const counter = new Counter();

// Observer updates automatically
autorun(() => {
  console.log(`Current count: ${counter.count}`);
});

// Modify count
counter.count++;
```

### Computed Values

The `@computed` decorator creates computed values based on observables, updating automatically when dependencies change.

```javascript
class Counter {
  // ...
  @computed get isEven() {
    return this.count % 2 === 0;
  }
}

// Computed value updates automatically
autorun(() => {
  console.log(`Is count even: ${counter.isEven}`);
});

// Modify count
counter.count++;
```

### Reactions

Use `autorun`, `reaction`, or `when` functions to create reactions that execute automatically when data changes. `autorun` runs whenever dependencies change, while `reaction` runs on specific condition changes.

```javascript
// Reactive UI update
reaction(
  () => counter.count,
  (newCount) => {
    updateUI(newCount);
  },
);

// Conditional reaction
when(
  () => counter.count > 10,
  () => {
    console.log('Count exceeds 10!');
  },
);
```

### Actions

The `@action` decorator or `action` function marks functions that modify state, ensuring changes occur in a controlled environment to prevent unintended side effects.

```javascript
class Counter {
  // ...
  @action increment() {
    this.count++;
  }
}

counter.increment();
```

### Automatic Dependency Tracking

MobX uses proxies and the visitor pattern to automatically track dependencies for computed values and reactions, eliminating manual dependency management.

## Dependency Tracking

MobX uses proxies and the visitor pattern to track which computed values and observers depend on observable state, enabling efficient updates.

### Proxies

MobX leverages ES6 Proxy objects to create proxies for observable objects. Proxies intercept access and modification operations, allowing MobX to detect when observable state is read or modified.

```javascript
const observableValue = observable(42);
const proxyValue = new Proxy(observableValue, mobxHandler); // mobxHandler contains interception logic
```

### Visitor Pattern

When accessing observable object properties, MobX records the access path using the visitor pattern, creating a dependency tree that tracks which computed values or reactions depend on which observables.

```javascript
class ObservableObject {
  @observable prop;
  // ...
}

const obj = new ObservableObject();
autorun(() => {
  console.log(obj.prop);
});

// Accessing obj.prop records the dependency
obj.prop = "new value";
```

### Change Notifications

When an observable state changes, MobX notifies all dependent computed values and reaction functions. Since dependencies are tracked, only affected computations and reactions are triggered.

### Minimized Updates

Dependency tracking ensures only necessary computed values and reactions are executed, improving performance by avoiding redundant calculations.

### Optimizations

MobX provides optimization mechanisms, such as using `asFlat`, `asReference`, or `asStructure` methods to control how proxies handle changes, further enhancing performance.

## Middleware Integration

While MobX is not as tightly integrated with middleware as Redux, you can use `mobx-react-devtools` to monitor state changes, offering features like time-travel debugging.

### Installing the Plugin

Install `mobx-react-devtools` using npm or yarn:

```bash
npm install --save mobx-react-devtools
# or
yarn add mobx-react-devtools
```

### Integrating into Your Application

In your main application file (typically `index.js` or `App.js`), import and include the `mobxReactDevTools` component:

```jsx
import { Provider } from 'mobx-react';
import { mobxReactDevTools } from 'mobx-react-devtools';

// Assuming you have your store
const store = new YourStore();

ReactDOM.render(
  <Provider {...store}>
    <YourApp />
    {/* Add DevTools below your app */}
    <mobxReactDevTools />
  </Provider>,
  document.getElementById('root')
);
```

### Enabling Developer Tools

Once your application is running, a new panel in the browser’s developer tools displays your MobX state and change history. In Chrome or Firefox, find it under the “.mobx-react-devtools” or “Extensions” panel.

### Time Travel Debugging

While `mobx-react-devtools` does not directly support time-travel debugging, you can use `mobx-state-tree`, a MobX-compatible library that provides time-travel functionality by creating a reversible operation history.

## TypeScript Support

MobX integrates well with TypeScript, offering type safety and improved code hints.

### Type Annotations

In TypeScript, add type annotations to observables, computed values, and actions for type safety.

```typescript
import { observable, computed, action } from 'mobx';

class Counter {
  @observable count: number = 0;

  @computed
  get isEven(): boolean {
    return this.count % 2 === 0;
  }

  @action
  increment(): void {
    this.count++;
  }
}
```

### Interfaces

Define interfaces for complex observable object structures to ensure data model consistency.

```typescript
interface Todo {
  id: number;
  title: string;
  completed: boolean;
}

class TodoStore {
  @observable todos: Todo[] = [];

  // ...
}
```

### Type Inference

TypeScript automatically infers computed value types based on their dependencies.

### Type Guards

Use type guard functions to ensure type-safe access to observable objects.

```typescript
function isTodo(item: any): item is Todo {
  return item && typeof item.id === 'number' && typeof item.title === 'string';
}

const todo = getTodoFromSomewhere();

if (isTodo(todo)) {
  // TypeScript knows `todo` is of type `Todo`
  console.log(todo.title);
}
```

### Type Extensions

Extend `ObservableObject`, `ObservableArray`, and `ObservableMap` types to better describe your data.

### makeObservable and makeAutoObservable

In MobX 6, use `makeObservable` and `makeAutoObservable` for initializing observable state, providing better type safety and automatic type inference.

```typescript
class TodoStore {
  private todos: Todo[] = [];

  constructor() {
    makeAutoObservable(this);
  }

  // ...
}
```

## Reactive Data Flow

MobX’s reactive data flow ensures data changes automatically propagate to dependent computations and views, clarifying the relationship between data models and UI.

```jsx
import React from 'react';
import { render } from 'react-dom';
import { observable, computed, action, reaction } from 'mobx';
import { Provider, observer } from 'mobx-react';

// Create observable object
const counterStore = {
  @observable count: 0,

  @action increment() {
    this.count++;
  },

  @computed get doubleCount() {
    return this.count * 2;
  },
};

// Create a reaction to print doubleCount when count changes
reaction(
  () => counterStore.count,
  (newCount) => {
    console.log(`Double count: ${counterStore.doubleCount}`);
  },
);

// Create a React component to observe count changes
const Counter = observer(({ store }) => (
  <div>
    <p>Count: {store.count}</p>
    <button onClick={() => store.increment()}>Increment</button>
    <p>Double Count: {store.doubleCount}</p>
  </div>
));

// Render the application
render(
  <Provider counterStore={counterStore}>
    <Counter />
  </Provider>,
  document.getElementById('root'),
);
```

In this example, `counterStore` is an observable object with a `count` property. `doubleCount` is a computed value that calculates based on `count`. When `count` increments, both `doubleCount` and the `Counter` component update automatically without manual `setState` calls.

The `reaction` function creates an observer that prints `doubleCount` when `count` changes, forming a clear reactive data flow.

## Reactive Functions

Using `autorun`, `reaction`, or `when` functions, you can create functions that execute automatically based on data changes, running until a condition is met or manually stopped.

```javascript
const disposer = reaction(
  () => todoList.completedCount,
  (completedCount) => console.log(`There are ${completedCount} completed todos`),
);

// Later, to stop the reaction:
disposer();
```

## Responsive API Calls

For API calls with MobX, wrap asynchronous operations in `runInAction` to ensure state updates occur in the correct scope.

```javascript
async function fetchData() {
  await someAsyncCall().then(data => {
    runInAction(() => {
      // Update state
      myStore.setData(data);
    });
  });
}
```

## Microkernel Architecture

MobX’s core is lightweight, allowing selective inclusion of additional features like `mobx-state-tree` or `mobx-react-form` for enhanced state management and form handling.

### mobx-state-tree

`mobx-state-tree` is a MobX-based state management library offering strong type safety, state snapshots, time-travel debugging, and robust error handling.

```typescript
import { types, onSnapshot } from 'mobx-state-tree';

const Todo = types.model({
  title: types.string,
  completed: types.boolean,
});

const TodoStore = types.model({
  todos: types.array(Todo),
}).actions(self => ({
  addTodo(title: string) {
    self.todos.push(Todo.create({ title, completed: false }));
  },
}));

const store = TodoStore.create({ todos: [] });

onSnapshot(store, (snapshot) => {
  console.log('State snapshot:', snapshot);
});

store.addTodo('Learn MobX');
```

### mobx-react-form

`mobx-react-form` is a library for creating and managing forms, integrating seamlessly with MobX and providing validation, submission, and reset functionalities.

```jsx
import React from 'react';
import { Form, Field } from 'mobx-react-form';
import { observable, action } from 'mobx';
import { Provider, observer } from 'mobx-react';

const schema = {
  name: 'form',
  fields: ['name', 'email'],
  labels: { name: 'Name', email: 'Email' },
  validators: {
    name: 'required',
    email: 'required|email',
  },
};

class MyForm extends Form {
  constructor(values = {}) {
    super(schema, values);
    this.plugins({
      dvr: {},
    });
  }
}

const form = new MyForm();

@observer
class MyComponent extends React.Component {
  @observable submitting = false;

  @action submitForm = () => {
    this.submitting = true;
    if (form.validate()) {
      alert('Form submitted successfully!');
      form.reset();
    } else {
      form.focus();
    }
    this.submitting = false;
  };

  render() {
    return (
      <Provider form={form}>
        <form onSubmit={this.submitForm}>
          <Field type="text" name="name" />
          <Field type="email" name="email" />
          <button type="submit" disabled={this.submitting}>
            Submit
          </button>
        </form>
      </Provider>
    );
  }
}

render(<MyComponent />, document.getElementById('root'));
```

These libraries extend MobX’s core functionality, providing advanced abstractions for state management and form handling. This microkernel architecture allows you to choose tools based on project needs, keeping the project lightweight and modular.

## Integration with Other Libraries

MobX is not limited to React; it integrates well with Vue.js, Angular, and other libraries. It can also coexist with Redux or other state management libraries for specific use cases.

## Hot Reloading and Development Tools

MobX, combined with the `mobx-react-devtools` plugin, provides capabilities for inspecting data flow, tracking dependencies, and analyzing performance during development, supporting hot reloading for rapid iteration.

## Performance Optimization

MobX’s reactive system automatically tracks dependencies, updating views only when necessary, which is typically more efficient than manual updates. For performance issues, use `makeObservable` or `makeAutoObservable` with `asStructure` or `asReference` options, and `trackTransitions` to fine-tune performance.

## Design Patterns

MobX encourages design patterns like MVC (Model-View-Controller), MVVM (Model-View-ViewModel), or MST (MobX State Tree) to better organize and manage state.
