cookiewaffles
cookiewaffles

Reputation: 57

Y scroll event listener useEffect

My code underneath is a simple React component that sets a new state upon scrolling the page down. If the Y scroll exceeds a certain position it will set another state to true.

    const [ scrollPosition, setScrollPosition ] = useState(0);
    const [ confetti, setConfetti ] = useState(false);

    useEffect(
        () => {
            window.addEventListener('scroll', handleScroll, { passive: true });
            check();

            return () => {
                window.removeEventListener('scroll', handleScroll);
            };
        },
        [ scrollPosition ]
    );
    const handleScroll = () => {
        const position = window.pageYOffset;
        setScrollPosition(position);
    };
    
    const check = () => {
        if (scrollPosition > 400) {
            setConfetti(true);
        }
        if (scrollPosition < 401) {
            setConfetti(false);
        }
    };

Everything is working smoothly as expected but I was just wondering if there is a less expensive way of doing this. Re-rendering the page every time Y scroll changes seems like a very inefficient way to run this code. I don't think throttling would be a good idea either as there might be a delay when a user scrolls down really fast. Thanks to anyone who can help!

Upvotes: 1

Views: 3305

Answers (2)

anjalipatodia
anjalipatodia

Reputation: 1

In useEffect Hook , the value pass in last array depends the call the render method. Whenever value in array change useEffect call and subsequently render method invoke. Better you remove array value.

 useEffect(
    () => {
        window.addEventListener('scroll', handleScroll, { passive: true });
        check();

        return () => {
            window.removeEventListener('scroll', handleScroll);
        };
    },
    []
);

Upvotes: 0

awamas
awamas

Reputation: 26

You don't need to save the scroll position in the state.

useEffect(() => {
    window.addEventListener("scroll", handleScroll, { passive: true });

    return () => {
        window.removeEventListener("scroll", handleScroll);
    };
}, [scrollPosition]);
const handleScroll = () => {
    const position = window.pageYOffset;
    if (position > 400) {
        setConfetti(true);
    }
    if (position < 401) {
        setConfetti(false);
    }
};

Upvotes: 1

Related Questions