I use onscroll event in my React component like this:
import React, { Component } from 'react';
import throttle from 'lodash/throttle';
class Example extends Component {
state = {
navigationFixed: false,
}
componentDidMount() {
window.addEventListener('scroll', this.throttledHandleScroll);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.throttledHandleScroll);
}
handleScroll = () => {
this.contentRef && this.setState({
navigationFixed: window.scrollY >= this.contentRef.offsetTop - 32,
});
throttledHandleScroll = throttle(this.handleScroll, 80); // Using lodash throttle here
render() {
//Some variables and components here
...
<section
className={cx(s.content, {
[s.navigationFixed]: this.state.navigationFixed,
})}
id="content"
ref={(ref) => {this.contentRef = ref}}
>
...
//Another components here
</section>
}
};
And this is works fine, but it get freeze sometimes, I guess it is because of handleScroll function, which fires too often. So my question is how can I optimise this code?
Try this modification to the handleScroll method.
handleScroll = () => {
if(!this.contentRef) return;
const navShouldBeFixed = window.scrollY >= this.contentRef.offsetTop - 32
if(this.state.navigationFixed && !navShouldBeFixed) {
this.setState({navigationFixed: false});
} else if (!this.state.navigationFixed && navShouldBeFixed) {
this.setState({navShouldBeFixed: true})
}
}
EDIT: Less lines of code.
handleScroll = () => {
if(!this.contentRef) return;
const navShouldBeFixed = window.scrollY >= this.contentRef.offsetTop - 32
if(this.state.navigationFixed && !navShouldBeFixed ||
!this.state.navigationFixed && navShouldBeFixed) {
this.setState({navigationFixed: navShouldBeFixed});
}
}
This way the setState method is only fired when the UI requires a change.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With