React component for asynchronously fetching data
npm install --save async-data-access
This component will load data asynchronously using the provided fetch
function, and pass through status values and payload via the render-props pattern to a provided child render method. An optional transform
function can be given to transform the fetched response into a different format.
AsyncDataAccess is agnostic about how data is fetched, with only the expectation that the fetching will be performed asynchronously. This means that it can be written using a modern async
function, or alternatively using a Promise
. The fetch method can potentially make multiple API calls and gather their results together.
Props accepted by this component are:
{
// `fetch` is the method to fetch data
fetch: PropTypes.func.isRequired,
// `transform` method that can be used for transforms on fetched data,
// the intention being that `fetch` can be simple and error handling done before transforming attempted
transform: PropTypes.func,
// `onError` handler that will be called if an error occurs
onError: PropTypes.func,
}
Props passed through to render child, with their types are:
{
isFetching: PropTypes.bool, // Flag to indicate fetch is in progress
didInvalidate: PropTypes.bool, // Flag that indicates current fetch invalidated payload
lastFetchFailed: PropTypes.bool, // Flag that indicates last fetch failed
lastError: PropTypes.string, // String representing last error message received
payload: PropTypes.any, // Payload from fetch, defaults to null
reload: PropTypes.func // Function to trigger a reload
}
import React, { Component } from 'react'
import AsyncDataAccess from 'async-data-access'
class Example extends Component {
fetcher = async () => {
// fetch data asynchronously from a server
return await fetch('http://example.com/movies.json')
}
transformer (response) {
// transform response to a different format (if required)
return response.movieList
}
render () {
return (
<AsyncDataAccess fetch={this.fetcher} transform={this.transformer}>
{
props => {
const { isFetching, payload } = props;
const movies = payload || [];
return <>
{ isFetching && <h2>Loading data</h2> }
{
movies.map(
({ title, description }) => <>
<h3>{title}</h3>
<div>{description}</div>
</>
)
}
</>
}
}
</AsyncDataAccess>
)
}
}
MIT © stevesims