2
\$\begingroup\$

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 }
\$\endgroup\$

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.