Code Monkey home page Code Monkey logo

react-bottom-scroll-listener's Introduction

react-bottom-scroll-listener npm NPM version npm bundle size (minified)

A simple React hook and React component that lets you listen for when you have scrolled to the bottom.

Window

Example

Container

Example

Installation

npm: npm install react-bottom-scroll-listener

yarn: yarn add react-bottom-scroll-listener

Migrating to V5

Version 5 is only a refactor for the hook to use an options parameter, instead of relying of function parameters which were starting to get out of hand.

If you are using the component, there are no breaking changes

If your hook looks like this:

useBottomScrollListener(callback, 0, 200, undefined, true);

You will have to change it to use the options parameter:

useBottomScrollListener(callback, {
  offset: 100,
  debounce: 0,
  triggerOnNoScroll: true
})

Remember that you can omit any values that are using the defaults! The defaults are ase following:

  offset: 0,
  debounce: 200,
  debounceOptions: { leading: true },
  triggerOnNoScroll: false,

So for the average use case, you are probably only setting one of these values, so your hook might look like this:

useBottomScrollListener(callback, { triggerOnNoScroll: true })

You can refer to the Usage-section for more details.

Usage

Hook

Full example

On bottom of entire screen

Use the hook in any functional component, the callback will be invoked when the user scrolls to the bottom of the document

import { useBottomScrollListener } from 'react-bottom-scroll-listener';

useBottomScrollListener(callback);

On bottom of specific container

Use the hook in any functional component, use the ref given from the hook and pass it to the element you want to use as a scroll container

The callback will be invoked when the user scrolls to the bottom of the container

import { useBottomScrollListener } from 'react-bottom-scroll-listener';

const scrollRef = useBottomScrollListener(callback);

<div ref={scrollRef}>Callback will be invoked when this container is scrolled to bottom.</div>;

Parameters

useBottomScrollListener<T extends HTMLElement>(
  // Required callback that will be invoked when scrolled to bottom
  onBottom: () => void,
  // Options, entirely optional, you can provide one or several to overwrite the defaults
  options?: {
    // Offset from bottom of page in pixels. E.g. 300 will trigger onBottom 300px from the bottom of the page
    offset?: number
    // Optional debounce in milliseconds, defaults to 200ms
    debounce?: number
    // Overwrite the debounceOptions for lodash.debounce, default to { leading: true }
    debounceOptions?: DebounceOptions
    // If container is too short, enables a trigger of the callback if that happens, defaults to false
    triggerOnNoScroll?: boolean
  },
); // returns React.MutableRefObject Optionally you can use this to pass to a element to use that as the scroll container

Component

Full example

On bottom of entire screen

Simply have the BottomScrollListener anywhere in your application and pass it a function as onBottom-prop.

import BottomScrollListener from 'react-bottom-scroll-listener';

<BottomScrollListener onBottom={callback} />;

On bottom of specific container

Pass the BottomScrollListener a function inside the JSX_tag, receive the scrollRef in this function from the BottomScrollListener and pass it to the component you want to listen for a scroll event on.

import BottomScrollListener from 'react-bottom-scroll-listener';

<BottomScrollListener onBottom={callback}>
  {(scrollRef) => <div ref={scrollRef}>Callback will be invoked when this container is scrolled to bottom.</div>}
</BottomScrollListener>;

Those are some weird children, what's going on?

This pattern is called "function as a child". What this allows is that the BottomScrollListener can pass you a React.RefObject. This React.RefObject can then be passed to whatever component you want to be notified when you hit the bottom of. Without this it would be difficult to attach event listeners for scrolling to an arbitrary element.

Props

Property Type Default Description
onBottom Function null (required): callback invoked when bottom is reached
debounce number 200 milliseconds, how much debounce there should be on the callback
offset number 0 offset from bottom in pixels. E.g. 300 if it should invoke onBottom 300px before the bottom.
debounceOptions DebounceOptions {leading: true} see the lodash.debounce options: see https://lodash.com/docs/4.17.15#debounce
triggerOnNoScroll boolean false if container is too short, enables a trigger of the callback if that happens
children React.Node or Function null Not required, but you can use this to wrap your components. Most useful when you have some conditional rendering. If this is a function, that function will receive a React.RefObject that needs to be passed to a child element. This element will then be used as the scroll container.

Migrating from 2.x.x to 3.x.x

There are no breaking changes except that the required version of React is now 16.8.0. If you are on an older version of React you can either upgrade React, or stay on version 2.x.x. If you already are on a newer version of React you don't have to do anything, except maybe try out the new hook implementation. :)

react-bottom-scroll-listener's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

react-bottom-scroll-listener's Issues

Inner Scrolling Question

Hello! I have a small fixed height container that has an inner scrolling element that I need to attach this listener to. Can you show me an example of what the children prop accepts and how I should set up my components to achieve this? Thanks so much.

Leaving bottom state

Hello. Is there any way that I can listen to another event like when I leave bottom scroll?

useBottomScrollListener useEffect runs before ref has been set

I've been trying to use the useBottomScrollListener hook but it seems that at the time the useEffect hooks runs and checks for if (ref != null) that the ref has not had a chance to finish being set on my container element. I wonder if the useEffect hook needs to have added to its dependency array containerRef.current if that's possible. useEffect needs to somehow wait or re-run after containerRef.current has been set but it seems it runs too quickly and has no way of running again once containerRef.current has been updated.

Bottom Scroll Listener with tabs

Hi,

I have 2 tabs on a page, each has its own pagination and hence has a Bottom Scroll Listener, each.
Issue is, when I reach the bottom of tab A, it hits the onBottom function of tab B as well, and vice versa.
How can I have 2 separate independent listeners on each tab?

My pseudo code structure is -
Parent Class -

<Tab A>
        <ChildClass></ChildClass>
</Tab A>

<Tab B>
        <ChildClass></ChildClass>
</Tab B>

Child Class -

<BottomScrollListener onBottom={this.fetchMorePosts}>
         <Posts></Posts>
</BottomScrollListener>

Issue on 3840 x 2160 resolution

Hello,

I have noticed an issue for 3840 x 2160 resolution screens, where on onBottom callback prop will not fire. For resolutions below that, it appears to be fine. Are you able to replicate this, and if so, have a fix?

Thanks!

Useless debounce

The debounce blocks the firing of the first event, making it completely useless for it's intended purpose.

Warning: React.createElement: type is invalid. Got Object.

I get the following warning when I use BottomScrollListener as a component:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

When I comment out the component below, the warning is gone.

<BottomScrollListener
    onBottom={this.checkForFetchRows}
    offset={this.state.scrollOffset}
    triggerOnNoScroll={false}
/>

I'm using version 4.1.0

Component specific container callback does not fire

I have downloaded your repo and tested this on your example web app. When scrolling to the bottom of the inner-scroll-example element, the alert dialog does not fire.

This is also reproduced in my own application.

I am currently using:

  • node v12.16.3
  • npm v6.14.4
  • React v17.0.0

notOnBottom properity

Hey,
I used your npm package react-bottom-scroll-listener in order to hide my footer component until I reach the bottom, but the problem now is that I need to re-hide it once I am no longer in bottom, which I don’t see an easy way to do, without creating a scroll event. So Is there any possibility for you to add a notOnBottom property.
This is for a university project, and I would appreciate if you added this feature as soon as possible
Thanks.

Specific container behaviour

I'm trying to set up a listener on specific container but callback func is called even if I scroll to bottom of body : behaviour of scrolling to bottom of body.

const containerRef = useBottomScrollListener(handleContainerOnBottom);

This line creates a body listener even I link JSX Element with reference

Listener for "Scroll To Top" event.

Hi,

I'm working on a chat module in which chat messages are shown in reverse sequence. So all new messages will come to the bottom and by default, the app will focus on the new message. For the older messages, I want to use pagination so that I shouldn't call the function to fetch all the messages at once, instead I wanna use a limit. Whenever I scroll to the top and listener will call for the previous messages that are not being fetched yet.

For this purpose, I want to listen when the scroll is reached to the top. Is there any way of using this library for my purpose? Thanks in advance.

hi,i got a problem in chrome 61.0.3163.100

it works only in first time when scroll the page to bottom, when append the new data into list it does not work in the callback.

is any wrongs in (line 20-24)

 handleOnScroll() {
    if (document.body.scrollHeight - this.props.offset <= (document.body.scrollTop + window.innerHeight)) {
      this.props.onBottom();
    }
  }

document.body.scrollTop always in 0,
this problem is only occur in new version desktop chrome, i got no problem yet, and the code run perfect in mobile device

use it in iframe

is it possible to detect the scroll into an iframe in my component with this function ?

Reset ref after reloading component

Hello,
I'm using this lib and I think it's light and useful but I have one problem. I implemented for a table using infinite scroll and I don't know if we have a way to reset the ref after reloading the table or not?

Consider leading:true on debounce

Currently, there is a useless delay of debounce (default 200ms) before the first onBottom callback which could be avoided by enabling the leading option. This is especially noticeable when one specifies a high debounce like 1000. I see no reason to not set this option, further callbacks can be debounced, but the first should not.

another option as object not function parameter

Hi,

greate hook :) I would like to use option as object not function parameters.

useBottomScrollListener(
   onBottomCallback,
   {
      offset = 0, 
      debounce = 200,   // Optional debounce in milliseconds, defaults to 200ms
      debounceOptions,  // Overwrite the debounceOptions for lodash.debounce, default to { leading: true }
      triggerOnNoScroll,// If container is too short, enables a trigger of the callback if that happens, defaults to false
   }        
)

then you can setup interface option a only one option can be overrided. Now I need to fullfill offset, debounce, debounceOptions and than I am able to set triggerOnNoScroll which was important for me.

Thanks,
Daniel

use named options for hook

currently the hook is using positioned options, which are hard to specify only wanted override since there many options

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.