Box
A box is a state node with a unique key and typed operations.
const countBox = numberBox('count');
const userBox = objectBox('user', { id: 0, name: '' });
Choosing A Box
Pick the box that matches the state structure.
numberBox('count');
boolBox('modal.open');
arrayBox<string>('names');
objectBox('settings', { theme: 'system' });
listBox<number>('todo.ids');
mapBox('names.byId', 0, '');
recordBox('user', UserRecord);
recordMapBox('todos', TodoRecord, 'id');
listMapBox('todos.byUser', 0, 0);
mapMapBox('matrix', 'row', 'column', 0);
Each box exposes mutations and selectors that match the shape. A NumberBox has add; a
RecordMapBox has mergeItem; a ListMapBox has pushIn.
Initial State
Boxes define their initial state.
const countBox = numberBox('count', 10);
Some boxes accept constructors or infer-only arguments for TypeScript.
class TodoRecord extends Record<Todo>({
id: 0,
title: '',
completed: false,
}) {}
const todoMapBox = recordMapBox('todos', TodoRecord, 'id');
Updating State
Box methods create mutations.
dispatch(countBox.add(1));
dispatch(userBox.set('name', 'Ada'));
dispatch(todoMapBox.mergeItem({ id: 1, title: 'Write docs' }));
The base setState mutation is available on every box.
dispatch(countBox.setState(0));
dispatch(countBox.setState((count) => count + 1));
dispatch(countBox.setState()); // reset to initial state
Selecting State
Pass a box to select to read its full state.
const count = select(countBox);
Box-specific selector methods derive smaller values.
const title = select(todoMapBox.getIn(1, 'title'));
const exists = select(todoMapBox.hasItem(1));
Configuring Boxes
Use config for box options such as persistence.
const settingsBox = objectBox('settings', {
theme: 'system',
}).config({
persist: { version: 1 },
});
Use setInitialState when you want to derive or extend the initial state.
const userMapBox = recordMapBox('users', UserRecord, 'id').setInitialState((state) => {
return state.mergeItem({ id: 1, name: 'Amos' });
});
Responding To Signals
Boxes can subscribe to signals and update themselves.
userMapBox.subscribe(signOutSignal, (state, event) => {
return event.keepData ? state : state.deleteItem(event.userId);
});
This is useful for cleanup and cross-module events.