JSFiddle - React, Tailwind, and code Playground

HTML

<button class="js-refresh">refresh</button>
<div id="feed" class="feed"></div>
<div id="feed2" class="feed"></div>

CSS

/* Styles go here */

.tweet {
  padding: 50px;
  background-color: #ccc;
  margin-top: 10px;
}

.feed {
  margin: 10px 0;
}

JavaScript

// Code goes here
function infiniteScroll(options) {
  var defaultOptions = {
    binder: $(window), // parent scrollable element
    loadSpot: 300, //
    feedContainer: $("#feed"), // container
    cb: function() {},
  }

  options = $.extend(defaultOptions, options);
  options.shouldLoad = true;

  var returnedOptions = {
    setShouldLoad: function(bool) {
      options.shouldLoad = bool;
      if (bool) {
        scrollHandler();
      }
    },
  };

  function scrollHandler() {
    var scrollTop = options.binder.scrollTop();
    var height = options.binder[0].innerHeight || options.binder.height();
    if (options.shouldLoad && scrollTop >= (options.binder[0].scrollHeight || $(document).height()) - height - options.loadSpot) {
      options.shouldLoad = false;
      if (typeof options.cb === "function") {
        new Promise(function(resolve) {
          resolve();
        }).then(function() {
          return options.cb();
        }).then(function(isNotFinished) {
          if (typeof isNotFinished === "boolean") {
            options.shouldLoad = isNotFinished;
          }
        });
      }
    }
  }

  options.binder.scroll(scrollHandler);

  scrollHandler();

  return returnedOptions;

}

function tweetLoader() {
  var amountLoaded = 0;
  var numToLoad = 10;
  var maxLoad = 100;

  function loadTweets($el) {
    if (amountLoaded !== maxLoad) {
      var lastLoadIndex = Math.min(maxLoad, amountLoaded + numToLoad);
      for (var i = amountLoaded; i < lastLoadIndex; ++i) {
        addTweet($el, i);
      }
      amountLoaded = lastLoadIndex;
      return true;
    } else {
      return false;
    }
  }

  function addTweet($el, i) {
    $el.append('<div class="tweet">Tweet #' + (i + 1) + '</div>');
  }

  return {
    addTweet: addTweet,
    loadTweets: loadTweets,
    resetAmountLoaded: function() {
      amountLoaded = 0
    }
  }
}

$(document).ready(function() {

  var tl = tweetLoader();
  var infScroll = infiniteScroll({
    cb: function() {
     ...