Immer.js Integration
CxJS requires all data to be immutable. Each change (update) operation is required to return a new object.
This can be very challenging with complex and deeply nested data models, especially for developers who
are not used to that.
Immer.js can help greatly with that, especially in combination with typed data models.
In order to use Immer.js, you need to install immer and cx-immer npm packages.
npm install immer cx-immer
Once installed you should enable Immer in CxJS stores. This should be done on application startup.
import { enableImmerMutate } from "cx-immer";
enableImmerMutate();Once this is implemented you can use the mutate method for updating data in the store.
Controller.ts
export default class extends Controller<PageModel> {
// Example 1: Before (immutable operation)
onAddTodo(text: string) {
this.store.update(
$page.todos,
todos => [...todos, { id: uid(), text, completed: false }]
);
}
// Example 1: After
onAddTodo(text: string) {
this.store.mutate(
$page.todos,
todos => {
// No issues with mutating data directly inside the mutate method
todos.push({ id: uid(), text, completed: false });
// It's not required to return anything
}
);
}
// Example 2: Before
onMarkComplete(id: string) {
this.store.update(
$page.todos,
updateArray,
todo => ({ ...todo, completed: true }),
todo => todo.id == id
);
}
// Example 2: After
onMarkComplete(id: string) {
this.store.mutate(
$page.todos,
todos => {
let todo = todos.find(t => t.id === id);
todo.completed = true;
}
);
}
}