Using classes
Classes allows you to co locate state and logic. It can be a good idea to think about your classes as models. They model some state.
overmind/models.js
1
class LoginForm {
2
constructor() {
3
this.username = ''
4
this.password = ''
5
}
6
get isValid() {
7
return Boolean(this.username && this.password)
8
}
9
reset() {
10
this.username = ''
11
this.password = ''
12
}
13
}
Copied!
overmind/state.js
1
import { LoginForm } from './models'
2
3
export const state = {
4
loginForm: new LoginForm()
5
}
Copied!
It is important that you do NOT use arrow functions on your methods. The reason is that this binds the context of the method to the instance itself, meaning that Overmind is unable to proxy access and track mutations
You can now use this instance as normal and of course create new ones.

Serializing class values

If you have an application that needs to serialize the state, for example to local storage or server side rendering, you can still use class instances with Overmind. By default you really do not have to do anything, but if you use Typescript or you choose to use toJSON on your classes Overmind exposes a symbol called SERIALIZE that you can attach to your class.
1
import { SERIALIZE } from 'overmind'
2
3
class User {
4
constructor() {
5
this.username = ''
6
this.jwt = ''
7
}
8
toJSON() {
9
return {
10
[SERIALIZE]: true,
11
username: this.username
12
}
13
}
14
}
Copied!
If you use Typescript you want to add SERIALIZE to the class itself as this will give you type safety when rehydrating the state.
1
import { SERIALIZE } from 'overmind'
2
3
class User {
4
[SERIALIZE] = true
5
username = ''
6
jwt = ''
7
}
Copied!
The SERIALIZE symbol will not be part of the actual serialization done with JSON.stringify

Rehydrating classes

The rehydrate utility of Overmind allows you to rehydrate state either by a list of mutations or a state object, like the following:
overmind/actions.js
1
import { rehydrate } from 'overmind'
2
3
export const updateState = ({ state }) => {
4
rehydrate(state, {
5
user: {
6
username: 'jenny',
7
jwt: '123'
8
}
9
})
10
}
Copied!
Since our user is a class instance we can tell rehydrate what to do, where it is typical to give the class a static fromJSON method:
overmind/models.js
1
import { SERIALIZE } from 'overmind'
2
3
class User {
4
[SERIALIZE]
5
constructor() {
6
this.username = ''
7
this.jwt = ''
8
}
9
static fromJSON(json) {
10
return Object.assign(new User(), json)
11
}
12
}
Copied!
overmind/actions.js
1
import { rehydrate } from 'overmind'
2
3
export const updateState = ({ state }) => {
4
rehydrate(
5
state,
6
{
7
user: {
8
username: 'jenny',
9
jwt: '123'
10
}
11
},
12
{
13
user: User.fromJSON
14
}
15
)
16
}
Copied!
It does not matter if the state value is a class instance, an array of class instances or a dictionary of class instances, rehydrate will understand it.
That means the following will behave as expected:
overmind/state.js
1
import { User } from './models'
2
3
export const state = {
4
user: null, // Can be existing class instance or null
5
usersList: [], // Expecting an array of values
6
usersDictionary: {} // Expecting a dictionary of values
7
}
Copied!
overmind/actions.js
1
import { rehydrate } from 'overmind'
2
3
export const updateState = ({ state }) => {
4
rehydrate(
5
state,
6
{
7
user: {
8
username: 'jenny',
9
jwt: '123'
10
},
11
usersList: [{...}, {...}],
12
usersDictionary: {
13
'jenny': {...},
14
'bob': {...}
15
}
16
},
17
{
18
user: User.fromJSON,
19
usersList: User.fromJSON,
20
usersDictionary: User.fromJSON
21
}
22
)
23
}
Copied!
Note that rehydrate gives you full type safety when adding the SERIALIZE symbol to your classes. This is a huge benefit as Typescript will yell at you when the state structure changes, related to the rehydration
Last modified 5mo ago
Copy link