Cerebral uses a single state tree to store all the state of your application. Even though you split up your state into modules, at the end of the day it will look like one big tree:
{
title: 'My Project',
someOtherModule: {
foo: 'bar'
}
}
Cerebral’s state management is built on several key principles:
These principles make your application more predictable and easier to debug.
Let’s expand our application with more state to manage posts and users:
import { App } from 'cerebral'
import Devtools from 'cerebral/devtools'
const app = App({
state: {
title: 'My Project',
posts: [],
users: {},
userModal: {
show: false,
id: null
},
isLoadingPosts: false,
isLoadingUser: false,
error: null
}
}, {...})
When modeling your state, you’ll need to decide how to structure your data. There are two main approaches:
For our posts and users, we’ve chosen different storage approaches:
{
posts: [
{ id: 1, title: 'Post 1', userId: 1 },
{ id: 2, title: 'Post 2', userId: 2 }
],
users: {
'1': { id: 1, name: 'User 1' },
'2': { id: 2, name: 'User 2' }
}
}
The decision depends on how you’ll access the data:
For example, to display a user in our modal:
// With object storage - O(1) constant time lookup
const user = users[userModal.id]
// With array storage - O(n) linear time search
const user = users.find((user) => user.id === userModal.id)
Objects also naturally prevent duplicate entries with the same ID, since object keys must be unique.
In Cerebral, you access state using the state
tag:
import { state } from 'cerebral'
// In a component
connect({
title: state`title`,
posts: state`posts`
})
// In an action
function myAction({ get }) {
const title = get(state`title`)
const posts = get(state`posts`)
}
You can also use a cleaner object notation syntax if you configure the babel-plugin-cerebral in your project:
import { state } from 'cerebral'
// In a component
connect({
title: state.title,
posts: state.posts
})
// In an action
function myAction({ get }) {
const title = get(state.title)
const posts = get(state.posts)
}
State can only be updated in actions using the store provider:
function setTitle({ store }) {
store.set(state`title`, 'New Title')
}
function addPost({ store, props }) {
store.push(state`posts`, props.post)
}
We’ll explore more about state operations in later sections.