Actions
Overview
Actions in neutrix provide a way to handle complex state changes and async operations. They're particularly useful when you need to:
- Coordinate multiple state updates
- Handle async operations like API calls
- Process data before updating state
- Manage loading and error states
When to Use Actions
Use actions when you need to:
- Call an API or do something async
- Update multiple things at once
- Show loading states
- Handle errors
That's really it! The main thing to remember is: if you need to do something more complex than just set, use an action.
Creating actions
1. Using Store Action Creator
typescript
const store = createNeutrixStore({
users: [],
loading: false,
error: null
});
const fetchUsers = store.action(
async (store) => {
store.set('loading', true);
try {
const users = await api.getUsers();
store.set('users', users);
return users;
} finally {
store.set('loading', false);
}
}
);
2. Using Initial State (Hook Store Only)
typescript
const useStore = createNeutrixStore({
count: 0,
increment: async (state) => {
return { count: state.count + 1 };
}
});
Using Actions in Components
1. Using useNeutrixAction Hook
typescript
function UserList() {
const { loading, error, execute } = useNeutrixAction(
async (store) => {
const users = await api.getUsers();
store.set('users', users);
}
);
return (
<div>
<button onClick={execute} disabled={loading}>
Load Users
</button>
{error && <div>Error: {error.message}</div>}
</div>
);
}
2. Using Store-Created Actions
typescript
function UserManager() {
const { loading, error, execute } = useNeutrixAction(
async (store, userId: string, data: UserData) => {
store.set(`users.${userId}.updating`, true);
try {
const user = await api.updateUser(userId, data);
store.set(`users.${userId}`, user);
} finally {
store.set(`users.${userId}.updating`, false);
}
}
);
return <UserForm onSubmit={execute} />;
}
Action features
Batch updates
typescript
const checkout = store.action(async (store) => {
store.batch([
['cart', []],
['orderStatus', 'processing'],
['lastOrder', { id: '123', items: [] }]
]);
});
Type safety
typescript
interface UserState {
users: User[];
loading: boolean;
error: string | null;
}
const useUserStore = createNeutrixStore<UserState>({
users: [],
loading: false,
error: null
});
const fetchUsers = useUserStore.store.action(
async (store) => {
store.set('loading', true);
try {
const users = await api.getUsers();
store.set('users', users);
} catch (error) {
store.set('error', error.message);
}
}
);