Skip to content

ViewModelSimple ​

ViewModelSimple is a minimal contract aligned with the ViewModel interface, designed for lightweight state management with MobX. It keeps reactive state initialization simple (for example, via makeAutoObservable) while still fitting the library lifecycle in React / Solid applications.

Reference to source code

API Signature ​

ts
interface ViewModelSimple<Payload, ParentViewModel>

All members are optional except that you usually keep your own reactive state and actions.

MemberDescription
id?: stringUnique instance id. Optional on the class; React / Solid generate one when creating the instance. Pass config.id when using ViewModelStore directly.
parentViewModel?: ParentViewModelReact / Solid integrations assign this to simple VMs from the active parent after calling mount(); direct store registration exposes the parent through init(config) but does not assign this property.
init?(config)Called when the instance is connected to a ViewModelStore.
mount?() / unmount?()Optional lifecycle hooks.
setPayload?(payload)Optional payload updates from the view layer.

When to Use ​

Use ViewModelSimple when:

  1. You need direct control over MobX observability (e.g., using makeAutoObservable)
  2. You prefer a simple, boilerplate-free class structure
  3. Your view model does not require advanced features like viewModels access or complex lifecycle hooks.

Example ​

ts
import { ViewModelSimple } from "mobx-view-model";
import { makeAutoObservable } from "mobx";

export class FruitViewModel implements ViewModelSimple {
  // Unique instance identifier
  id = crypto.randomUUID(); 

  // Observable state
  fruit = "apple";

  constructor() {
    // Initialize MobX observables
    makeAutoObservable(this);
  }

  // Example action
  setFruit(newFruit: string) {
    this.fruit = newFruit;
  }
}

defining id property is optional

If you do not define the id property, the React / Solid integrations generate an instance id. When using ViewModelStore directly, pass config.id; the default store implementation does not generate one.

Example without implementing any interface methods ​

ts
import { ViewModelSimple } from "mobx-view-model";
import { makeAutoObservable } from "mobx";

export class FruitViewModel {
  // Observable state
  fruit = "apple";

  constructor() {
    // Initialize MobX observables
    makeAutoObservable(this);
  }

  // Example action
  setFruit(newFruit: string) {
    this.fruit = newFruit;
  }
}

implements ViewModelSimple was removed

Because TypeScript throws an error about not implementing at least one property or method of the ViewModelSimple interface.

Usage in React ​

Usage with withViewModel HOC ​

tsx
import { observer } from "mobx-react-lite";
import { withViewModel } from "mobx-view-model-react";
import { FruitViewModel } from "./model";

export const FruitComponent = withViewModel(FruitViewModel, ({ model }) => {
  return (
    <div>
      <p>Current fruit: {model.fruit}</p>
      <button onClick={() => model.setFruit("banana")}>
        Change to Banana
      </button>
    </div>
  );
});

Usage with useCreateViewModel hook ​

tsx
import { observer } from "mobx-react-lite";
import { useCreateViewModel } from "mobx-view-model-react";
import { FruitViewModel } from "./model";

export const FruitComponent = observer(() => {
  // Creates a single instance per component mount
  const vm = useCreateViewModel(FruitViewModel);

  return (
    <div>
      <p>Current fruit: {vm.fruit}</p>
      <button onClick={() => vm.setFruit("banana")}>
        Change to Banana
      </button>
    </div>
  );
});

Accessing Instances ​

To retrieve an existing instance elsewhere in your app:

  1. Use the useViewModel hook.
  2. Ensure the instance is registered in a ViewModelStore

Usage in SolidJS ​

Usage with withViewModel HOC ​

tsx
import { withViewModel } from "mobx-view-model-solid";
import { FruitViewModel } from "./model";

export const FruitComponent = withViewModel(FruitViewModel, (props) => {
  return (
    <div>
      <p>Current fruit: {props.model.fruit}</p>
      <button onClick={() => props.model.setFruit("banana")}>
        Change to Banana
      </button>
    </div>
  );
});

Usage with useCreateViewModel hook ​

tsx
import { useCreateViewModel } from "mobx-view-model-solid";
import { FruitViewModel } from "./model";

export const FruitComponent = () => {
  const vm = useCreateViewModel(FruitViewModel);

  return (
    <div>
      <p>Current fruit: {vm.fruit}</p>
      <button onClick={() => vm.setFruit("banana")}>
        Change to Banana
      </button>
    </div>
  );
};

Accessing instances ​

  1. Use useViewModel.
  2. Register instances via ViewModelStore + ViewModelsProvider.