React hooks to interact with an API from a stateless component using axios.
npm i react-api-hooks -s
Basic usage of the useInfAPI
hook to scroll through a list of books from the Google Books API.
Use the react-infinite-scroller
component to track scrolling, and call fetchPage
when required.
By default the hook expects the API to paginate using a parameter called offset
and that the API returns an array of items.
If these defaults do not work for your API, then you will need to provide your own paginator
and responseToItems
functions.
const InfScrollExample = () => { const { items, error, isPaging, hasMore, fetchPage } = useInfAPI( booksURL, { params: booksInitialParams }, paginator, responseToItems ); if (error) { return <Error error={error} />; } return ( <div style={{ overflow: 'auto', height: 400, border: '1px solid #eee' }}> <InfiniteScroll pageStart={0} loadMore={() => { if (!isPaging) { fetchPage(); } }} hasMore={hasMore} loader={<div key={0}>Loading</div>} useWindow={false} > <GoogleBooksListInner items={items} /> </InfiniteScroll> </div> ); }; InfScrollExample.propTypes = {}; export default InfScrollExample;
const pageSize = 5; /** * Google Books Paginator function. * * Alter the axios `config` object to fetch the next page. * * Update the `paginationState` object to keep track of page numbers internally. * * @param config {Object} - The axios config object passed to the hook. * @param paginationState {Object} - An object kept in state to keep track of pagination. */ export function paginator(config, paginationState) { const { params = {} } = config; const { startIndex = 0 } = paginationState; const newIndex = startIndex + (params.maxResults || pageSize); const updatedParams = { ...params, startIndex: newIndex }; const updatedConfig = { ...config, params: updatedParams }; const updatedPaginationState = { startIndex: newIndex }; return [updatedConfig, updatedPaginationState]; } /** * Google Books Item Extractor * * Return a list of items to the hook, given the axios response object. * * @param response {Object} - The axios response object. */ export function responseToItems(response) { const { items } = response.data; const hasMore = items.length === pageSize; return [items, hasMore]; }