Using Immer
As you know, when working with immutable objects you often get to what’s called a “spread hell” situations. If you prefer working with immutable objects in an mutable fashion, you can use immer with Akita.
The only thing you need to do is pass the produce
function from immer
to your store:
todos.store.ts
import { produce } from 'immer';
export interface TodosState extends EntityState<Todo> {
ui: {
filter: VISIBILITY_FILTER
};
}
const initialState = {
ui: { filter: VISIBILITY_FILTER.SHOW_ALL }
};
@StoreConfig({ name: 'todos', producerFn: produce })
export class TodosStore extends EntityStore<TodosState> {
constructor() {
super(initialState);
}
}
Now when you use the store's update
function, you'll get the draft
version, which you can mutate:
todos.service.ts
export class TodosService {
constructor(private todosStore: TodosStore) { }
updateFilter(filter: VISIBILITY_FILTER) {
this.todosStore.update(state => {
state.ui.filter = filter;
})
}
complete({ id, completed }: Todo) {
this.todosStore.update(id, entity => {
entity.completed = completed;
});
}
}
danger
When you choose to work with immer
, you can't return a new value from the callback function:
todosStore.update(id, entity => entity.completed = completed);
This will cause immer
to throw. Here's a live example you can play with.