My first go at a Higher Order Component in react.
Aims to give a component the ability to call an url repeatedly with a given refresh interval.
Seems to be working as I want. I'm not 100% confident that I'm using async/await correctly.
<MyComponent refresh={interval} url={`https://reqres.in/api/users?per_page=${count}`} />
The HOC:
import React from 'react'
import PropTypes from 'prop-types';
const apiCaller = () => WrappedComponent =>
class extends React.Component {
static propTypes = {
url: PropTypes.string.isRequired,
refresh: PropTypes.number.isRequired
}
static defaultProps = {
url: '',
refresh: 0
}
state = {
error: null,
data: null,
loading: false
}
componentWillUnmount() {
clearInterval(this.timer)
}
async componentDidMount() {
try {
// Call URL and wait for complete.
await this.callApi(this.props.url)
// Set up the refresh
this.timer = setInterval(
() => this.callApi(this.props.url),
this.props.refresh * 1000
)
} catch (e) {
this.setState({
loading: false,
error: e
})
}
}
async componentWillReceiveProps(nextProps) {
try {
if(this.props.url !== nextProps.url || this.props.refresh !== nextProps.refresh) {
// Get rid of the old timer.
clearInterval(this.timer)
// Call URL and wait for complete.
await this.callApi(nextProps.url)
// Set up the refresh again.
this.timer = setInterval(
() => this.callApi(nextProps.url),
nextProps.refresh * 1000
)
}
} catch (e) {
this.setState({
loading: false,
error: e
})
}
}
async callApi(url){
this.setState({
loading: true
})
const response = await fetch(url)
const json = await response.json()
this.setState({
data : json.data,
loading: false
})
}
render(){
return <WrappedComponent {...this.state} {...this.props} />
}
}
export { apiCaller }