MobX Depot Logo

MobX Depot

Docs

Get started
Models
Queries
Mutations
Root store
Caching
React hooks

Root store

mobx-depot generates a RootStore to manage instances of your data. Whenever a mutation or query is dispatched, that data is deeply resolved by the RootStore in order to instantiate any models that are returned.

For example, given the following response:


{
"data": {
"user": {
"__typename": "User",
"id": 1,
"name": "John Doe"
}
}
}

RootStore will realize that data.user should be a UserModel and will instantiate it. If the User model has any nested models, they will be instantiated as well.

Existing instances are preserved

If a model instance already exists in the RootStore, it will be updated with the new data. This means that if you have a UserModel instance in your RootStore and you dispatch a mutation or query that returns a UserModel with the same ID, the existing record will be updated with the new data.

Of course, as a result of MobX's reactivity, any components or logic that is observing any affected records will automatically update.

Gotcha: New data can get duplicated

Consider the following scenario:

  1. A local UserModel is created within a RegisterForm component
  2. The user fills out the form and submits it
  3. The RegisterForm component dispatches a mutation that creates a new UserModel on the server
  4. The RootStore resolves a new UserModel from the response and instantiates it

There will be two UserModel instances: one that was created locally and one that was created by the server, stored in the RootStore. This is because the local instance is not stored in the RootStore, but more importantly, the IDs are not the same either.

But what if there's state within the local UserModel that you want to preserve? The RootStore provides a replace method that allows you to replace an existing model instance with another one. Here's an example:


import { getRootStore } from './depot';
const rootStore = getRootStore();
class UserModel extends UserBaseModel {
password = "";
save() {
const createUser = new CreateUserMutation({
input: {
email: this.email,
password: this.password
}
});
createUser.dispatch().then((response) => {
// Problem: response.data.createUser is a new instance of the `UserModel` that the `RootStore` resolved.
// It is not the same instance as `this`. The solution is to copy the data from the server's instance,
// and replace the one in the `RootStore` with this.
// 1. Copy the data from the persisted instance to the local instance.
// The `assign` method is provided by the `UserBaseModel`, which is generated by `mobx-depot`.
// It is available in all models. Note: This will also copy the ID of the server's instance.
this.assign(response.data.createUser);
// 2. Replace the RootStore's instance with this local one.
// `this.store` is a reference to the `RootStore`, which is provided by the `UserBaseModel`.
rootStore.replace(response.data.createUser, this);
});
}
}

Any observers that were observing the server's instance will now be observing the local instance.