webapp/channels/src/actions/CLAUDE.OPTIONAL.md
actions/mattermost-redux and @mattermost/client.actions/
├── *.ts # Domain-specific actions (channel_actions.ts, post_actions.ts, etc.)
└── views/ # UI-specific actions (modals, sidebars, etc.)
All async thunks must return {data: ...} on success or {error: ...} on failure.
export function fetchSomething(id: string): ActionFuncAsync {
return async (dispatch, getState) => {
try {
const data = await Client4.getSomething(id);
dispatch({type: ActionTypes.RECEIVED_SOMETHING, data});
return {data};
} catch (error) {
forceLogoutIfNecessary(error, dispatch, getState);
dispatch(logError(error));
return {error};
}
};
}
For simple API calls, use bindClientFunc helper for standard error handling:
export function fetchUser(userId: string): ActionFuncAsync {
return bindClientFunc({
clientFunc: Client4.getUser,
params: [userId],
onSuccess: ActionTypes.RECEIVED_USER,
});
}
{data} on success or {error} on failure (see webapp/STYLE_GUIDE.md → Redux & Data Fetching).Client4 only inside actions; components should dispatch actions, never hit APIs directly.hooks.ts, apps.ts) rather than duplicating inside multiple actions.channels/src/packages/mattermost-redux, then consume selectors here.forceLogoutIfNecessary(error) and dispatch logError.trackEvent, perf) when adding analytics inside thunks.DelayedDataLoader for batching multiple calls.UI state actions that don't involve server data (modals, sidebars, view state) dispatch to state.views.* reducers rather than state.entities.*.
channel_actions.test.ts).nock or request-mocking utilities in mattermost-redux tests for complex flows.channel_actions.ts, global_actions.tsx – canonical patterns for async thunks.mattermost-redux/src/actions/* – shared actions; import instead of duplicating server logic.