Telirw
Telirw

Reputation: 443

How to achieve better performance on scroll event in React

I want to add a color background to navbar if the user scrolls down. When the value of the scrollY equals 0, the background of nav becomes transparent.

I added a scroll event in the componentDidMount life cycle method. Inside this I put a function that changes state. It works, but when I scroll the performance drops dramatically, I have no idea how to make it more smoothly.

While state.open equals true the nav element receive class.

componentDidMount() {

window.addEventListener("scroll", this.activeNavTab, {
  passive: true,
  });
 }

activeNavTab() {
 if (window.scrollY > 0) {
   this.setState(() => ({ navTab: true }));
 } else {
  this.setState(() => ({ navTab: false }));
 }
}

componentWillUnmount() {
  window.removeEventListener("scroll", this.activeNavTab);
}

Question 2

Manipulating DOM elements in own custom method is a good practice? For example:

toggleMenu() {
 document.body.classList.toggle("disablescroll");
 this.setState((prevState) => ({ open: !prevState.open }));
}

Upvotes: 0

Views: 2249

Answers (1)

Dmitry Reutov
Dmitry Reutov

Reputation: 3032

Just don't call this.activeNavTab each time when scroll method works... Call it with delay...The easiest way to do it is to wrap your function with lodash function debounce. It should improve perfomance

const delay = 500
const activeNavTabDebounced = _.debounce(this.activeNavTab, delay)
window.addEventListener("scroll", activeNavTabDebounced, {
  passive: true,
});

and then kill it with

componentWillUnmount() {
  window.removeEventListener("scroll", activeNavTabDebounced);
}

Upvotes: 1

Related Questions