1

I am using react.js. What I am doing is when the user scrolls the page then I have to add the class to the header menu. I tried below code but it's not working.

I create a file in the public folder and added below the script in the index.html

 <script src="%PUBLIC_URL%/custom.js"></script>

custom.js

const header = document.getElementById("header_menu");

const sectionOneOptions = {
  rootMargin: "-200px 0px 0px 0px"
};

const sectionOneObserver = new IntersectionObserver(function(
  entries,
  sectionOneObserver
) {
  entries.forEach(entry => {
    if (!entry.isIntersecting) {
      header.classList.add("menuscroll");
    } else {
      header.classList.remove("menuscroll");
    }
  });
},
sectionOneOptions);

Header.js

import React from 'react';
import ReactDOM from 'react-dom';
import {Link} from 'react-router-dom';

const HeaderMenu = () => {
    return (
        <header id="header_menu">
        <div className="right-menu float-right">
            <ul>
                <li><Link to={'/'} >Home</Link></li>
                <li><Link to={'/about'} >About Us</Link></li>
                <li><Link to={'/contact'} >Contact Us</Link></li>
            </ul>
        </div>
        </header>
        );
  }

  export default HeaderMenu;
user9437856
  • 2,360
  • 2
  • 33
  • 92

1 Answers1

2

One important thing to say is that when using react try your best not to manipulate the DOM yourself, that should be react's job.

In useEffect, we listen for the scroll event and then call a function. In that function I am checking if the classname has already been set, if it has then we don't want to update the state to avoid infinity loop, I also check if it the pageYOffset greater than or equal to 100px. I do vice versa to remove the classname when we get less than 100px

import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';

const HeaderMenu = () => {
    const [headerClassName, setHeaderClassName] = useState('');

    const handleScroll = (headerClassName) => {
        if (headerClassName !== 'menuscroll' && window.pageYOffset >= 100) {
            setHeaderClassName('menuscroll');
        } else if (headerClassName === 'menuscroll' && window.pageYOffset < 100) {
            setHeaderClassName('');
        }
    }

    React.useEffect(() => {
        window.onscroll = () => handleScroll(headerClassName);
    }, [headerClassName]); // IMPORTANT, This will cause react to update depending on change of this value

    return (
        <header id="header_menu" className={headerClassName}>
            <div className="right-menu float-right">
                <ul>
                    <li><Link to={'/'} >Home</Link></li>
                    <li><Link to={'/about'} >About Us</Link></li>
                    <li><Link to={'/contact'} >Contact Us</Link></li>
                </ul>
            </div>
        </header>
    );
}

export default HeaderMenu;

You can also test on codepen

rotimi-best
  • 1,852
  • 18
  • 29