This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// When abort happens, this error will be throw | |
class AbortError extends Error { | |
constructor(message: string = 'Aborted') { | |
super(message); | |
this.name = 'AbortError'; | |
} | |
} | |
// General interface of Abortable | |
interface Abortable { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Imagine we defined a thunk action creator from routine | |
const fetchData = getThunkActionCreator(fetchDataRoutine, async (id: number) => { | |
return await api.fetchData(id); | |
}); | |
// We could write another thunk action creator to access the existing state | |
const fetchDataWithIdFromState = () => (dispatch: Dispatch, getState: () => RootState) => { | |
const id = getState().somewhere.id; | |
return dispatch(fetchData(id)); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Use type guards | |
const reducer = (state: State = initState, action: Action<any>): State => { | |
// isSuccessAction is a type guard | |
if (fetchDataRoutine.isSuccessAction(action)) { | |
// action is typed as Action<DataType>, so payload is DataType | |
const payload = action.payload; | |
// ... | |
} | |
// isFailureAction is a type guard |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type ValidAction = | |
| ReturnType<typeof fetchDataRoutine.request> | |
| ReturnType<typeof fetchDataRoutine.success> | |
| ReturnType<typeof fetchDataRoutine.failure>; | |
const reducer = (state: State = initState, action: ValidAction): State => { | |
// The reducer logic goes here... | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const reducer = (state: State = initState, action: Action<any>): State => { | |
// The reducer logic goes here... | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fetchData = getThunkActionCreator( | |
fetchDataRoutine, | |
async (id: number) => { | |
return await api.fetchData(id); | |
}, | |
{ | |
// this is optional | |
getRequestPayload: async (id: number) => { | |
return { | |
overwrittenPayload: id |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fetchData = getThunkActionCreator(fetchDataRoutine, async (id: number) => { | |
return await api.fetchData(id); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1. Define a routine | |
const fetchDataRoutine = createThunkRoutine<DataType>('FETCH_DATA'); | |
// Or explicitly decalre the error type if need | |
// const fetchDataRoutine: createThunkRoutine<DataType, Error>('FETCH_DATA') | |
// 2. Define the thunk action creator | |
// Note: We will address the repetitive logic flow later on | |
const fetchData = (id: number) => async (dispatch: Dispatch) => { | |
await dispatch(fetchDataRoutine.request(id)); | |
try { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1. Define the constants that are used as action types | |
const FETCH_DATA_REQUEST = 'FETCH_DATA/REQUEST'; | |
const FETCH_DATA_SUCCESS = 'FETCH_DATA/SUCCESS'; | |
const FETCH_DATA_FAILURE = 'FETCH_DATA/FAILURE'; | |
// 2. Define synchronous action creators (following Flux Standard Action) | |
const fetchDataRequest = (payload?: any) => { | |
if (typeof payload === 'undefined') { | |
return { | |
type: FETCH_DATA_REQUEST |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// To know more about ducks, see https://github.com/erikras/ducks-modular-redux | |
import { Action } from 'redux-actions'; | |
import { RootState } from '../../store'; | |
import { createSelector } from 'reselect'; | |
// State | |
// To know more about Record type, see https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt | |
export type ErrorState = Record<string, Error | null>; |