Home > Software design >  Make an onScroll function dynamic
Make an onScroll function dynamic

Time:08-29

So, i have this setFixed function. And i want to reuse it in another component too. But as it also handles with state and eventListener, idk how to do it. Please i need help!

CODE:

const NavBar = () => {
  const [fix, setFix] = useState(false);

  function setFixed() {
    if (window.scrollY > 0) {
      setFix(true);
    } else {
      setFix(false);
    }
  }
  window.addEventListener("scroll", setFixed);
  return (
    <div className={fix ? `${styles.navbar} ${styles.sticky}` : styles.navbar}>
      <div className={styles["nav-wrapper"]}>
        <div className={styles["img-wrapper"]}>
          <img className={styles.logo} src={Logo} alt="" />
        </div>
        <ul className={styles["navbar-links"]}>
          <li className={styles["navbar-links__item"]}>
            <a>Home</a>
          </li>
          <li className={styles["navbar-links__item"]}>
            <a>About</a>
          </li>
          <li className={styles["navbar-links__item"]}>
            <a>Contact</a>
          </li>
        </ul>
      </div>
    </div>
  );
};

export default NavBar;

CodePudding user response:

You have to put your event listener in a useEffect to avoid throw an event on each render, if you want reusable code you can make a custom hook like this:

 const useIsFixed = () => {

    const [isFixed, setIsFixed] = useState(false);

    useEffect(() => {
        function setFixed() {
            if (window.scrollY > 0) {
              setIsFixed(true);
            } else {
                setIsFixed(false);
            }
          }
        window.addEventListener("scroll", setFixed);

        return () => window.removeEventListener("scroll", setFixed);
    }, [])

    return isFixed
}

And then in your component

    const Container = () => {

const isFixed = useIsFixed()

 return (
    <div className={isFixed ? "fixed" : "sticky"}>
        
    </div>
 )
}

CodePudding user response:

You need to add event listener inside useEffect and remove it on unmount

const NavBar = () => {
  const [fix, setFix] = useState(false);

  function setFixed() {
    if (window.scrollY > 0) {
      setFix(true);
    } else {
      setFix(false);
    }
  }
  
  useEffect(() => {
    window.addEventListener("scroll", setFixed);

    return () => window.removeEventListener("scroll", setFixed);
  }, [])

  return (
    <div className={fix ? `${styles.navbar} ${styles.sticky}` : styles.navbar}>
      <div className={styles["nav-wrapper"]}>
        <div className={styles["img-wrapper"]}>
          <img className={styles.logo} src={Logo} alt="" />
        </div>
        <ul className={styles["navbar-links"]}>
          <li className={styles["navbar-links__item"]}>
            <a>Home</a>
          </li>
          <li className={styles["navbar-links__item"]}>
            <a>About</a>
          </li>
          <li className={styles["navbar-links__item"]}>
            <a>Contact</a>
          </li>
        </ul>
      </div>
    </div>
  );
};

export default NavBar;
  • Related