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.
API Signature
interface ViewModelSimple<Payload, ParentViewModel>All members are optional except that you usually keep your own reactive state and actions.
| Member | Description |
|---|---|
id?: string | Unique instance id. Optional on the class; React / Solid generate one when creating the instance. Pass config.id when using ViewModelStore directly. |
parentViewModel?: ParentViewModel | React / 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:
- You need
direct control over MobX observability(e.g., usingmakeAutoObservable) - You prefer a simple, boilerplate-free class structure
- Your view model does not require advanced features like
viewModelsaccess or complex lifecycle hooks.
Example
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
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
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
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:
- Use the
useViewModelhook. - Ensure the instance is registered in a
ViewModelStore
Usage in SolidJS
Usage with withViewModel HOC
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
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
- Use
useViewModel. - Register instances via
ViewModelStore+ViewModelsProvider.
