Skip to content

Instantly share code, notes, and snippets.

@ka2n
Created August 23, 2016 07:31
Show Gist options
  • Save ka2n/003380af058eb6357be51d4d64c18e6d to your computer and use it in GitHub Desktop.
Save ka2n/003380af058eb6357be51d4d64c18e6d to your computer and use it in GitHub Desktop.
import React from 'react'
import { PropTypes } from 'react'
import { throttle } from 'lodash'
export default class InfiniteList extends React.Component {
static propTypes = {
initialElements: PropTypes.arrayOf(PropTypes.node),
endElement: PropTypes.node,
moreElement: PropTypes.node,
onNext: PropTypes.func,
style: PropTypes.object
}
loading = false
lastKey = null
constructor(props) {
super(props)
this.state = {
elements: props.initialElements,
noMoreData: false,
}
}
render() {
return (
<ul style={this.props.style} onScroll={this.onScroll}>
{ this.state.elements }
<li>{ this.state.noMoreData ? this.props.endElement : this.props.moreElement }</li>
</ul>
)
}
onScroll = (e) => {
if (this.loading || this.state.noMoreData) {
return
}
const container = e.target
if (container.scrollTop > container.scrollHeight - container.offsetHeight - container.offsetHeight / 3) {
this.more()
}
}
more = () => {
if (this.loading || this.state.noMoreData) {
return
}
this.loading = true
if (!this.props.onNext) {
this.setState({ noMoreData: true })
return
}
this.props.onNext(this.lastKey).then(r => {
this.loading = false
return r
}).then(this.appendElements).catch(() => {
this.loading = false
})
}
appendElements = ({ elements, noMoreData, lastKey }) => {
this.lastKey = lastKey
this.setState({ elements: [...this.state.elements, ...elements], noMoreData })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment