Last updated: Apr 7, 2024
Reading time·5 min

div element in Reactwindow object in Reactdiv element in ReactTo handle the onScroll event in React:
onScroll prop on an element to listen for the scroll event.event.currentTarget.scrollTop property to get the number of
pixels the element is scrolled vertically.import {useState} from 'react'; export default function App() { const [scrollTop, setScrollTop] = useState(0); const handleScroll = event => { setScrollTop(event.currentTarget.scrollTop); }; return ( <div> <h2>Scroll Top: {scrollTop}</h2> <div style={{ border: '3px solid black', width: '400px', height: '100px', overflow: 'scroll', }} onScroll={handleScroll} > {[...Array(20)].map((_, index) => ( <p key={index}>Content {index}</p> ))} </div> </div> ); }

We set the onScroll prop on the div element, so every time the user scrolls
the horizontal or vertical axis of the div, the handleScroll function gets
invoked.
Notice that we used the currentTarget property on the event object to get
access to the element.
const handleScroll = event => { setScrollTop(event.currentTarget.scrollTop); };
currentTarget property on the event gives us access to the element that the event listener is attached to.On the other hand, the target property on the event gives us a reference to
the element that triggered the event (could be a descendant).
We used the Element.scrollTop property to get the number of pixels the element's content is scrolled vertically.
The last step is to update the state variable using the
useState hook.
setScrollTop(event.currentTarget.scrollTop);
The setScrollTop function takes care of updating the scrollTop state
variable every time the scrolls the vertical axis of the div.
If you need to set a conditional initial value for useState, check out
this article.
window object in ReactYou can use the
addEventListener() method
to handle the onScroll event on the window object.
scroll event listener to the window object in your useEffect
hook.window.scrollY property to get the number of pixels that the
document is vertically scrolled.import {useEffect, useState} from 'react'; const App = () => { const [scrollTop, setScrollTop] = useState(0); useEffect(() => { const handleScroll = event => { setScrollTop(window.scrollY); }; window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); }; }, []); return ( <div> <div style={{ position: 'fixed', padding: '10px 0', top: '0', backgroundColor: 'white', borderBottom: '3px solid black', width: '100%', }} > <h2>Scroll Top: {scrollTop}</h2> </div> <div style={{marginTop: '10rem'}}> {[...Array(100)].map((_, index) => ( <p key={index}>Content {index}</p> ))} </div> </div> ); }; export default App;

The addEventListener method takes the following 2 arguments:
| Name | Description |
|---|---|
| type | the type of the event to listen for |
| listener | a function to be invoked when the event is triggered |
The scroll event is triggered when the document view has been scrolled.
We passed an empty dependencies array to the
useEffect hook because we only
want to register the scroll event listener once - when the component mounts.
useEffect(() => { const handleScroll = event => { setScrollTop(window.scrollY); }; window.addEventListener('scroll', handleScroll); return () => { window.removeEventListener('scroll', handleScroll); }; }, []);
We used the window.scrollY property to update the scrollTop state variable.
The
window.scrollY
property on the window object returns the number of pixels that the document
is currently scrolled vertically.
If you set the onScroll prop on an element, you would use the
Element.scrollTop property instead as shown in the previous subheading.
useEffect hook is called when the component unmounts.return () => { window.removeEventListener('scroll', handleScroll); };
We used the removeEventListener() method to remove the event listener that we previously registered.
The removeEventListener method takes the following 2 arguments:
| Name | Description |
|---|---|
| type | the type of event for which to remove an event listener |
| listener | the event listener function of the event handler to remove from the event target |
The cleanup step is important because we want to make sure we don't have any memory leaks in our application.
The scrollTop property returns the number of pixels that an element's content
is scrolled vertically.
If you need to scroll to the bottom of a div, click on the link and follow the instructions.
To type the onScroll event of an element in React, set its type to
React.UIEvent<HTMLElement>.
The UIEvent type is used for onScroll events in React. You can access
properties on the element the event is attached to on the currentTarget
property.
const App = () => { const handleScroll = (event: React.UIEvent<HTMLElement>) => { console.log(event.currentTarget.scrollTop); console.log(event.currentTarget.offsetHeight); }; return ( <div style={{ border: '3px solid black', width: '400px', height: '100px', overflow: 'scroll', }} onScroll={handleScroll} > <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> </div> ); }; export default App;
We typed the event as React.UIEvent<HTMLElement> because the
UIEvent type is used for
onScroll events in React.
However, we could have been more specific when typing the event.
The easiest way for you to find out what the type of an event is, is to write
the event handler inline and hover over the event parameter in the function.
const App = () => { // 👇️ onScroll event is written inline // hover over the `event` parameter with your mouse return ( <div style={{ border: '3px solid black', width: '400px', height: '100px', overflow: 'scroll', }} onScroll={event => console.log(event)} > <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> </div> ); }; export default App;

event parameter and it shows me what the type of the event is.TypeScript is able to infer the type of the event when it's written inline.
This is very useful because it works with all events. Simply write a "mock"
implementation of your event handler inline and hover over the event parameter
to get its type.
Now that we know that the correct type for the onScroll event is
React.UIEvent<HTMLDivElement, UIEvent>, we can extract our handler function.
const App = () => { // 👇️ onScroll event is typed correctly now const handleScroll = (event: React.UIEvent<HTMLDivElement, UIEvent>) => { console.log(event.currentTarget.scrollTop); console.log(event.currentTarget.offsetHeight); }; return ( <div style={{ border: '3px solid black', width: '400px', height: '100px', overflow: 'scroll', }} onScroll={handleScroll} > <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> <p>Content</p> </div> ); }; export default App;
onScroll events.As long as you write the event handler function inline and hover over the
event parameter, TypeScript will be able to infer the event's type.
Notice that we used the currentTarget property on the event because we want to
access the element that the event listener is attached to.
The target property on the event gives us a reference to the element that
triggered the event.