Action
Actions are dispatchable workflows. They receive dispatch, select, and their own arguments.
import { action } from 'amos';
const addTodo = action(async (dispatch, select, title: string) => {
const todo = await api.createTodo({
userId: select(currentUserIdBox),
title,
});
dispatch([todoMapBox.mergeItem(todo), userTodoListBox.unshiftIn(todo.userId, todo.id)]);
});
Dispatch an action by calling the action factory.
await dispatch(addTodo('Write docs'));
When To Use Actions
Use actions for:
- async work
- updating several boxes together
- reading current state before deciding what to dispatch
- workflows that should appear as one debug action
Use box mutations directly for simple local updates.
Return Values
dispatch(action()) returns whatever the action actor returns.
const loadUser = action(async () => {
return api.getUser();
});
const user = await dispatch(loadUser());
If an action dispatches a mutation and returns it, the dispatch result is the mutation result.
Batched Updates
Actions can dispatch arrays.
dispatch([todoMapBox.mergeItem(todo), userTodoListBox.unshiftIn(todo.userId, todo.id)]);
The store notifies subscribers once after the root dispatch completes.
Conflict Policy
Actions support a leading concurrency mode.
const loadTodos = action(
async (dispatch, select, userId: number) => {
return api.getTodos(userId);
},
{
conflictPolicy: 'leading',
conflictKey: (select, userId) => userId,
},
);
When a matching action is already pending, Amos returns the existing promise instead of starting another one.
The default policy is always.
Selectable Actions
Bind an action to a selector or box with .select.
const getTodoList = action(async (dispatch, select) => {
const todos = await api.getTodos(select(currentUserIdBox));
dispatch(todoMapBox.mergeAll(todos));
}).select(selectVisibleTodos);
useQuery uses the bound selector to return useful store state while the action is pending or after
it completes.
Type Labels
The type option labels actions for devtools.
const signIn = action(async () => {}, {
type: 'users/signIn',
});
You can write it manually or use the Amos compiler transformer.