Skip to content

Instantly share code, notes, and snippets.

@osmanperviz
Created April 17, 2019 15:10
Show Gist options
  • Save osmanperviz/c3f50da76a253ff5a46d37ab918f3d70 to your computer and use it in GitHub Desktop.
Save osmanperviz/c3f50da76a253ff5a46d37ab918f3d70 to your computer and use it in GitHub Desktop.
RelayModern - React lazy load
import CircularProgress from '@material-ui/core/CircularProgress'
import debounce from 'lodash.debounce'
import PropTypes from 'prop-types'
import React, {Component} from 'react'
import Typography from '@material-ui/core/Typography'
import {withStyles} from '@material-ui/core/styles'
const styles = theme => ({
contentEnd: {
width: '100%',
textAlign: 'center'
},
progress: {
margin: theme.spacing.unit * 2
}
})
class LazyLoad extends Component {
constructor(props) {
super(props)
this.contentEndId = `content-end-${Math.floor(Math.random() * 999999)}`
}
componentDidMount() {
window.addEventListener('scroll', this.loadMoreIfEndIsVisible, true)
window.addEventListener('resize', this.loadMoreIfEndIsVisible, true)
this.loadMoreIfEndIsVisible()
}
componentDidUpdate() {
this.loadMoreIfEndIsVisible()
}
componentWillUnmount() {
window.removeEventListener('scroll', this.loadMoreIfEndIsVisible, true)
window.removeEventListener('resize', this.loadMoreIfEndIsVisible, true)
}
loadMoreIfEndIsVisible = debounce(
() => {
if (this.isEndVisible()) {
this.props.onLoadMore()
}
},
100,
{
maxWait: 500
}
)
isEndVisible = () => {
const element = document.getElementById(this.contentEndId)
if (!element) return
const rect = element.getBoundingClientRect()
return rect.top <= (window.innerHeight || document.documentElement.clientHeight)
}
render() {
const {className, classes, hasNextPage} = this.props
return (
<div id='lazy-load' className={className}>
{this.props.children}
{hasNextPage && (
<div className={classes.contentEnd} id={this.contentEndId}>
<CircularProgress className={classes.progress} />
<Typography>Wird geladen...</Typography>
</div>
)}
</div>
)
}
}
LazyLoad.propTypes = {
className: PropTypes.object.isRequired,
classes: PropTypes.object.isRequired,
hasNextPage: PropTypes.bool.isRequired,
onLoadMore: PropTypes.func.isRequired
}
export default withStyles(styles)(LazyLoad)
### Usage
<LazyLoad hasNextPage={hasNextPage} onLoadMore={onLoadMore}>
<div>
{someArray.map((item, index) =>
item
)}
</div>
</LazyLoad>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment