Daltron
Daltron

Reputation: 1866

ReactJS: On scroll, debounce - test scroll distance - if true - load more components

So, essentially, my own lazy loader... I want to fire a class method every time a scroll takes place and check to see if the user has scrolled to the bottom. If so, then load more components. I know there are packages for this (infinity-scroll / infinity-scroller), but I feel like I'm pretty close with my own code.

export default class Gallery extends Component {
  constructor(props) {
    super(props);
    this.state = {
      photos: [ // data from mongodb ],
      numberToLoad: 0,
    };

    this.handleScroll = _.debounce(() => this.loadMore(), 200);
  }

  handleScroll() {
    var hT = $('#contentBottom').offset().top,
    hH = $('#contentBottom').outerHeight(),
    wH = $(window).height(),
    wS = $(this).scrollTop();
    if (wS > (hT + hH - wH) && (hT > wS) && (wS+wH > hT + hH)) {
      // essentially, I want to call the class method to load more photos
      this.loadMore(); // doesn't work, wrong 'this' context
    }
  }

  loadMore() {
    this.setState({
      // increase photos returned with this.state.photos.slice(0, this.state.numberToLoad);
      // so, the user gets to the bottom, trigger the load more, to increase the slice
      numberToLoad: this.state.numberToLoad + 4, 
    });
  }

  render() {
    return (
    // I have tried <InfiniteScroll /> from 'react-infinite-scroller' but I'm not
// sure how to use it properly with pageStart, as I'm using array.slice()...
      <Component onScroll={this.handleScroll}>
        {this.renderPhotos()}
      </Component>
    )
  }
}

Okay, so that is the general code, I'm using debounce so that the scroll isn't triggering hundreds of checks.

Thoughts?

Errors I get:

Uncaught TypeError: this.loadMore is not a function

Upvotes: 0

Views: 2082

Answers (1)

Alex McMillan
Alex McMillan

Reputation: 17952

You need to bind your methods

this.handleScroll = _.debounce(this.loadMore.bind(this), 200);

Also, this line will immediately overwrite your definition of handleScroll, making it (the definition) redundant. Perhaps you meant:

this.handleScroll = _.debounce(this.handleScroll.bind(this), 200);

Also, as functions are first-class objects in Javascript, these 2 statements are essentially identical:

_.debounce(() => this.loadMore(), 200)
_.debounce(this.loadMore, 200)

Upvotes: 1

Related Questions