For redux itself, you can only dispatch action which is a plain JS object(or an action creator returns an action, this action is a plain JS object must have a type field.). But with various middlewares, you can dispatch various things such as a thunk, plain JS object action, etc. The middleware will transform the action to plain JS object action in the end.
When using the redux-thunk middleware, you can dispatch a thunk like this:
const thunkFunction = (dispatch, getState) => {
// logic here that can dispatch actions or read state
}
store.dispatch(thunkFunction)
The login thunk action creator does return a thunk.
A thunk action creator is a function that may have some arguments, and returns a new thunk function. See Writing Thunks
Another example, redux-promise-middleware,
Given a single action with an async payload, the middleware transforms the action to separate pending action and a separate fulfilled/rejected action, representing the states of the async action.
You can dispatch an action with async payload:
const response = dispatch({
type: 'FIRST',
payload: new Promise(...),
});
Answer from Lin Du on Stack Overflow