# React scroll decorator

DevFeed: [React scroll decorator](<https://devfeed.tech/articles/react-scroll-decorator-37340.md>)

Original publisher: [Read original article](<https://muffinman.io/blog/react-scroll-position-decorator/>)

Author: Stanko

Published: 2017-05-17T00:00:00Z

Content type: tutorial

Language: en

Sources: [Stanko Tadić](<https://devfeed.tech/sources/stanko-tadic.md>)

Topics: [React](<https://devfeed.tech/topics/react.md>), [React Component](<https://devfeed.tech/topics/react-component.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>)

Tags: [javascript](<https://devfeed.tech/tags/javascript.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [performance](<https://devfeed.tech/tags/performance.md>), [react](<https://devfeed.tech/tags/react.md>), [react-component](<https://devfeed.tech/tags/react-component.md>)

## AI overview

A tutorial presents a React scroll-position decorator that injects scroll position into component props. It uses a timed interval to throttle requestAnimationFrame checks instead of directly handling scroll events, while warning that applying it to many components may cause performance issues.

## Source excerpt

Update, December 2017 # Check this post for updated, more performant version. I love JavaScript decorators. One that I copy to every React project is scroll decorator. It is fairly simple way of injecting scroll position to react components. This way you can handle scroll using react lifecycle. This decorator is not listening to a scroll event, as that is the performance killer (especially when you push it to react lifecycle). Instead, it is using interval to check if scroll position has changed. To keep it performant, I'm using requestAnimationFrame. Interval is only there to throttle animation frame from triggering too often. Please note that it still may cause performance issues if you apply it to a large number of components. Personally, I never had to apply it to a more than three of four per page. So here it is: import React, { Component } from 'react'; const withScroll = ComposedComponent => class ScrollDecorator extends Component { constructor() { super(); // Initial scroll position this.state = { scrollPosition: this.getWindowScrollTop(), }; // Bind handlers this.handleInterval = this.handleInterval.bind(this); this.handleRequestAnimationFrame = this.handleRequestAnimationFrame.bind(this); } componentWillMount() { // 50 times per second, change to your needs const INTERVAL = 20; this.intervalID = setInterval(this.handleInterval, INTERVAL); } componentWillUnmount() { // Remove and reset interval/animationFrame clearInterval(this.intervalID); cancelAnimationFrame(this.requestID); this.requestID = null; this.intervalID = null; } getWindowScrollTop() { // Get scroll position, with IE fallback return window.pageYOffset || document.documentElement.scrollTop; } handleInterval() { // Interval is only used to throttle animation frame cancelAnimationFrame(this.requestID); this.requestID = requestAnimationFrame(this.handleRequestAnimationFrame); } handleRequestAnimationFrame() { const { scrollPosition } = this.state; const newScrollPosition = this.getWindowScrollTop()