Skip to content

Instantly share code, notes, and snippets.

@srph
Last active June 21, 2017 06:04
Show Gist options
  • Save srph/fd0fdce864554fac0945 to your computer and use it in GitHub Desktop.
Save srph/fd0fdce864554fac0945 to your computer and use it in GitHub Desktop.
react.js: a high-order component for infinite / load-more lists
import React, {PropTypes} from 'react';
import axios from 'axios';
/**
* @usage
* const InfinitePostsView = makeInfinite('/posts')(PostsView);
*/
const infinitePropType = PropTypes.shape({
data: PropTypes.array.isRequired,
isLoading: PropTypes.bool.isRequired,
isError: PropTypes.bool.isRequired,
isErrorMessage: PropTypes.string.isRequired,
isLastPage: PropTypes.bool.isRequired,
onLoadMore: PropTypes.func.isRequired
});
function makeInfinite(url) {
if ( !url ) {
throw new Error(`
The url must be provided, none provided.
`);
}
if ( typeof url !== 'string' ) {
throw new Error(`
The url must be a string, \`${typeof url}\` provided.
`);
}
return function(Component) {
class InfiniteComponent extends React.Component {
componentDidMount() {
this.handleLoadMore();
}
constructor(props) {
super(props);
this.state = {
collection: {
total: 0,
per_page: 0,
current_page: 0,
last_page: 0,
from: 0,
to: 0,
data: []
},
isLoading: false,
isError: false,
isErrorMessage: '',
isLastPage: false
};
this.handleLoadMore = this.handleLoadMore.bind(this);
}
render() {
const props = {
...this.props,
infinite: {
data: this.state.collection.data,
isLoading: this.state.isLoading,
isError: this.state.isError,
isErrorMessage: this.state.isErrorMessage,
isLastPage: this.state.isLastPage,
onLoadMore: this.handleLoadMore
}
};
return <Component {...props} />
}
handleLoadMore() {
if ( this.state.isLoading ) {
return;
}
this.setState({
isLoading: true,
isError: false,
isErrorMessage: ''
});
const page = this.state.collection.current_page + 1;
return axios.get(`${url}?page=${page}`)
.then((res) => {
this.setState((state) => ({
collection: {
...res.data,
data: [...state.collection.data, ...res.data.data]
},
isLoading: false,
isLastPage: res.data.current_page === res.data.last_page
}));
})
.catch((res) => {
this.setState({
isLoading: false,
isError: true,
isErrorMessage: 'Oops! The server is having issues right now. Try again!'
});
return Promise.reject(res);
});
}
}
return InfiniteComponent;
}
}
export {
makeInfinite as default,
infinitePropType as PropType
};
@srph
Copy link
Author

srph commented Mar 2, 2016

no docs yet.

@srph
Copy link
Author

srph commented Jun 21, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment