Data fetching component - React

by jonahe

HTML

<script src="https://unpkg.com/[email protected]/dist/react-with-addons.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.js"></script>
<div id="root"></div>

Babel + JSX

const FetchingLibrary = {
	get: (url) => {
  	// return a Promise that resolves some data after 3500ms
  	return new Promise((resolve, reject) => 
    	setTimeout(
      	// change to reject() to see the ErrorComponent
      	() => resolve({ data: {name: 'Apa', age: 99} })
        , 3500)
   	);
	}
};

const fetchHOC = url => (LoadingComponent, ErrorComponent) => {
	return React.createClass({
  	getInitialState() { 
    	return {data: null, error: false};
    },
    componentDidMount(){
    	FetchingLibrary.get(url)
      	.then( (a) => this.setState({data: a}) )
        .catch(e => this.setState({error: true}))
    },
    render() { 
    	if(this.state.error) return <ErrorComponent />;
      if(!this.state.data) return <LoadingComponent />;
      else return this.props.children(this.state.data);
  	}
  });
};

const UserLoading = () => <div>Loading user...</div>;
const UserError = () => <div>Failed to load user</div>;

const UserFetch = fetchHOC('/api/users')(UserLoading, UserError);

const User = ({name, age}) => (
	<div>
    Name: { name } <br/>
    Age: { age }
  </div>
);

const App = () => {
  return (
  	<div>
      <UserFetch>{ response => 
      	<User 
          name={ response.data.name } 
          age={ response.data.age } 
        />
      }</UserFetch>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));