Adding typed actions
Easy Peasy exports an Action
type, allowing you declare an action against your model interface. The signature for this type is:
type Action<
Model extends Object = {},
Payload = void
>
Type parameters
As you can see it accepts 2 type parameters, with both being optional. These type parameters can be described as follows.
Model
The model against which the action is being bound. This allows us to ensure the the
state
that is exposed to our action implementation is correctly typed.Payload
If you expect the action implementation to receive a payload then you should provide the type for the payload. If your action will not receive any payload you can omit this type parameter.
Declaring an Action
Let's define an action that will allow us to add a todo.
import { Action } from 'easy-peasy'; // 👈 import the type
export interface TodosModel {
items: string[];
addTodo: Action<TodosModel, string>; // 👈 declaring our action
}
We have provided type parameter to our Action
informing it that it is operating against the TodosModel
and that it should expect a payload of type string
.
Implementing an Action
We can now implement this action against our model.
import { action } from 'easy-peasy';
const todos: TodosModel = {
items: [],
addTodo: action((state, payload) => {
state.items.push(payload);
});
};
You will have noted that TypeScript was providing us with the typing information and assertions whilst we implemented our action.
Using an action
We can now consume the action within our components, whilst making sure that we use the typed useStoreActions
that we exported from our store.
import { useStoreActions } from '../hooks'; // 👈 import typed hook
function AddTodo() {
// map the addTodo action 👇
const addTodo = useStoreActions(actions => actions.todos.addTodo);
const [text, setText] = useState('');
const onButtonClick = useCallback(() => {
addTodo(text); // 👈 dispatch our action with the text describing the todo
setText('');
}, [addTodo, setText, text]);
return (
<>
<input value={text} onChange={e => setText(e.target.value)} type="text" />
<button onClick={onButtonClick}>Add Todo</button>
</>
);
}
Review
You can view the progress of our demo application here.