Redux Fetcher Compose is a library for data fetching and integrate @reduxjs/toolkit for React application
It features:
- Support Hooks, React Component, and Redux action to fetch and get data from API.
- Auto init reducer and action. It means, you not must declare a reducer to store response data.
- Support autosave response data to reducer base on URI (caching and prevent DRY code).
- Support transform response data getter.
- Support Abort Controller to abort request after unmount or client timeout.
- TypeScript ready.
- Support helper checks the status of data and requests.
- Add more hooks to trigger the request event.
- Can set timeout and parse the response for each request.
- Refetch request with previous props.
- All features supported by @reduxjs/toolkit
...and a lot more.
Inside your React project directory, run the following:
yarn add redux-fetcher-compose
Or with npm:
npm install redux-fetcher-compose
You can checkout example at CodeSandbox
fetcher.ts
import {
createFetcher,
createService,
ResponseParsed,
} from 'redux-fetcher-compose'
interface ExampleFetcherProps {
type: string
}
interface Post {
id: string
name: string
description: string
}
type RootState = any // Root reducers type;
const serviceCommon = createService({
domain: 'https://example.com/api',
requestTimeout: 10000
})
const ENTRY_POINT = 'example'
const fetcher = createFetcher<
ExampleFetcherProps,
RootState,
ResponseParsed<Post[]>,
>({
id: 'Example',
shouldKeepData: true,
uri: ({ props }) => props.type,
service: serviceCommon,
requestInfo: () => {
return {
entry: ENTRY_POINT,
options: {
method: 'GET',
},
}
},
})
export const {
action: getExampleAction,
component: ExampleFetcher,
useFetcherCompose: useExampleFetcherCompose,
useGetter: useExampleGetter,
useFetcher: useExampleFetcher
} = fetcher
App.tsx
import React from 'react'
import {
createAppState,
DataProvider
} from 'redux-fetcher-compose'
import { useExampleFetcherCompose } from './fetcher.ts'
const appState = createAppState({
enableReduxDevTools: true,
reducers: {}, // Root reducers
initialState: {},
})
export default function App () {
const [getter, refetch, abortController] = useExampleFetcherCompose({
type: 'news'
})
const handleRefetch = () => {
refetch()
}
return (
<DataProvider appState={appState}>
<h1>Hello Redux Fetcher Compose</h1>
<button onClick={handleRefetch}>Refetch</button>
<p>Fetcher data: {JSON.stringify(getter)}</p>
</DataProvider>
)
}
The function to create Redux store and app state context.
const appState = createAppState(options)
-
options
: an object of config React Redux.-
enableReduxDevTools: boolean = false
: (optional) whether to enable Redux DevTools integration. -
reducers: ReducersMapObject = {}
: (optional) a single reducer function that will be used as the root reducer. -
initialState: Object = {}
: (optional) an initial state value to be passed to the Redux createStore function. -
middleware = []
: (optional) an array of Redux middleware to install.
-
-
store
: the store of Redux, it's enhanced some feature to use for fetcher. -
appStateContext
: the value of React context.-
enhancedStore
: the Redux store. -
dispatch
: the function to dispatch Redux action.
-
The React component to wrap all components of the application to used Redux.
<DataProvider appState={appState}>
<App />
</DataProvider>
-
appState
: the app state created bycreateAppState
function. -
children
: the React component children.
The React context
import { useContext } from 'react'
const appStateContext = useContext(AppStateContext)
-
enhancedStore
: the Redux store. -
dispatch
: the function to dispatch Redux action.
This React hook returns a reference to the same Redux store that was passed into the <DataProvider>
component.
const enhancedStore = useStore()
The function to create a request service. It's can config API domain, request timeout, parse response of request, pass request options. Moreover, it provides some hooks to trigger events: pre-request, request success, request error. The return value of the function used in the fetcher config as a parameter.
const service = createService(options);
-
options
: the object to config service.-
domain: string = undefined
: (optional) the base domain to request API. -
requestTimeout: number = undefined
: (optional) set time (millisecond) to set timeout for request. -
responseParser: ResponseParser = defaultResponseParser
: the function to parse response. It's decide response of request is success or error. -
optionsModifier: OptionModifier = undefined
: the function to modify request options default. -
preRequestHook: FnPreRequestHook = undefined
: the function to trigger pre request called. -
requestSuccessHook: FnRequestSuccessHook = undefined
: the function to trigger response succeed. -
requestErrorHook: FnRequestErrorHook = undefined
: the function to trigger response error.
-
-
service: Service
: the function to use in fetcher config.
-
ResponseParser
: (response) => Promise -
OptionModifier
: (options) => RequestOptions-
options
: { getAppStateContext, requestInfo }
-
-
FnPreRequestHook
: (options) => void-
options
: { getAppStateContext, requestInfo, options }
-
-
FnRequestSuccessHook
: (options) => void-
options
: { getAppStateContext, requestInfo, options, responseParsed }
-
-
FnRequestErrorHook
: (options) => void-
options
: { getAppStateContext, requestInfo, options, responseParsed }
-
The function is used to define a fetcher. It's will create fetcher action, fetcher component, some hooks such as useFetcher, useGetter, useFetcherCompose.
/**
* @generator {FP}: Fetcher prop
* @generator {RS}: Root state,
* @generator {R}: Response,
* @generator {TR}: Transform response
* @param config
*/
const fetcher = createFetcher<FP, RS = any, R = any, TR = R>(config);
-
config
: the configuration object of fetcher.-
id: string = undefined
: (optional) the id of the fetcher. It's used to create a reducer to store response parsed. The field is optional, but if you want to use getter, that must be required. -
shouldKeepData: boolean = false
: (optional) the option help you keep fetcher data when component has use fetcher. It just work when you use useFetcher, useFetcherCompose, fetcher component. -
uri: FnFetcherURI = undefined
: (optional) the path to store response data in fetcher reducer. It useful when you call fetcher at many different contexts. Default fetcher will auto created path is@
. -
service: Service
: it service that fetcher used. Created bycreateService
. -
requestInfo: FnFetcherRequestInfo
: the function help declare are config of a request such as: domain, query, timeout, entry point, request options. -
shouldFetch: FnFetcherShouldFetch = defaultShouldFetch
: (optional) the function decided request call or not call. Default return true if the first call or current props different with previous props. -
preHandler: FnFetcherPreHandler = undefined
: (optional) the function will trigger before request called. -
onPending: FnFetcherOnPendingHandler = defaultOnPending
: (optional) the function will trigger while requesting API. -
onSuccess: FnFetcherOnSuccessHandler = defaultOnSuccess
: (optional) the function will trigger when response parsed was succeed. -
onError: FnFetcherOnErrorHandler = defaultOnError
: (optional) the function will trigger when response parsed was error.
-
-
action
: Redux action. When action dispatched then requesting API. -
component
: the React component. When component mounted then requesting API. But call or not call rely on the value returned of theshouldFetch
function. -
useFetcher
: the React hook to help you requesting API. But call or not call rely on the value returned of theshouldFetch
function. -
useGetter
: the React hook to help you get info of a request called stored in reducer base onuri
. -
useFetcherCompose
: the React hook that composeuseFetcher
anduseGetter
.
-
FnFetcherURI
: ({ props, getState }) => string;-
props
: Props to pass when use fetcher instance. -
getState
: Get state of root reducer.
-
-
Service
: ({ getAppStateContext, requestInfo, abortController, onPending, onSuccess, onError }) => Promise -
FnFetcherRequestInfo
: (props, getAppStateContext) => RequestInfo -
RequestInfo
: is a object.-
domain?
: string -
query?
: string | {} -
timeout?
: number -
entry
: string -
options
: RequestInit
-
-
FnFetcherShouldFetch
: ({ props, state, localState} ) => boolean;-
state
: is a root state. -
localState
: is a state of fetcher base onuri
.
-
-
FnFetcherPreHandler
: ({ props, getState, getAppStateContext, dispatch, localState }) => void -
FnFetcherOnPendingHandler
: ({ props, requestInfo, getState, localState, getAppStateContext, dispatch }) => any -
FnFetcherOnSuccessHandler
: ({ props, requestInfo, getState, localState, getAppStateContext, dispatch }) => TR | R -
FnFetcherOnErrorHandler
: ({ props, requestInfo, error, localState, getState, getAppStateContext, dispatch }) => TR | R
action: (props?: FP, abortController?: AbortController ) => any
-
props
: is a prop to pass in fetcher. -
abortController
: is a instance ofnew AbortController()
- When you dispatch action will return value, that returned
onSuccess
oronError
function that pass to config fetcher.
const [refetch, abortController] = useFetcher(props?: FP, defer?: boolean);
- Hook params:
-
props
: is a props will pass to fetcher. -
defer
: If settrue
then will not request API when hook mounted.
-
- Hook return value:
-
refetch
is a function to refetch API:(newProps? FP) => TR
-
abortController
is a instance of AbortController.
-
const getter = useGetter(props?: FP, transform?: (getter) => { ... })
- Hook params:
-
props
: is a props will pass to fetcher. -
transform
: is a function to transform data before return.
-
- Hook return one object include properties:
-
fetchStatus
: is a fetch status. -
dataStatus
: is a fetcher data status. -
value
: is a value returned byonPending
,onSuccess
oronError
-
previous
: is a previous getter after one action dispatched to change getter data. -
currentProps
: is current props to passed in fetcher. -
previousProps
: is previous props to passed in fetcher. -
isStatus
: is a function to check status of requestisStatus: (dataStatus: DataStatus) => boolean;
-
isLoading
: it istrue
: API requesting.
-
const [getter, refetch, abortController] = useFetcherCompose(props?: FP, transform?: (getter) => { ... });
- Hook params:
-
props
: is a props will pass to fetcher. -
defer
: If settrue
then will not request API when hook mounted.
-
- Hook return value:
-
getter
is a value returned by transform function. It a object same value returned byuseGetter
hook. -
refetch
is a function to refetch API:(newProps? FP) => TR
-
abortController
is a instance of AbortController.
-
<Component {...props} transform={(getter) => { ... }}>
<SomethingComponent />
</Component>
-
Component
will pass all props into fetcher. -
Component
has specific prop istransform
.transform: (getter) => {...}
-
SomethingComponent
will passed two props:getter
andrefetch
.-
getter
is a value returned by transform function. It a object same value returned byuseGetter
hook. -
refetch
is a function to refetch API:(newProps? FP) => TR
-
The function to check should fetch or shouldn't fetch API. By check, fetch data status is initial or previous props different current props.
The status of fetcher data.
-
Initial
: is the initial state. -
Initializing
: pending on the first request. -
Initialized
: done on the first request. -
Updating
: pending since the first request. -
Updated
: done since the first request. -
Loading
: is requesting. -
Error
: the response was an error. -
Success
: the response was succeeded. -
Aborted
: the response was aborted. -
Timeout
: the response timeout.
The status of the request.
Init
Pending
Done
Aborted
Timeout
The function using the qs
library. Help you parse query string to object with default ignoreQueryPrefix = true
.
const queryObject = parseQuery(query: string, options: IParseOptions)
The function using the qs
library. Help you parse query string to object with default addQueryPrefix = true
.
const queryString = stringifyQuery(query: Object, options: IStringifyOptions)
Service
FnFetcherShouldFetch
FnFetcherPreHandler
FnFetcherRequestInfo
FnFetcherURI
FnFetcherOnPendingHandler
FnFetcherOnSuccessHandler
FnFetcherOnErrorHandler
ResponseParsed
Use SemVer for versioning. For the versions available, see the tags on this repository.
Lê Quí Nhất - quinhatpy@gmail.com