Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

226
Vistas
React: How do I prevent the usage of useRef and useState to keep track of a same value in order to prevent useEffect from triggering?

currently I am making a navbar that only shows when you scroll up, to prevent useEffect to run everytime when the visible state get changed, I had to use both a ref and a state that is synced together to do comparison in the useEffect, using ref and a state to keep track of a same value seems extremely fishy, is there another way of doing this? one that does not involve triggering useEffect from creating the event handlers everytime the state changes?

import React, { useState, useRef, useEffect } from 'react';
import Link from 'next/link';

const NavbarLink = ({ name, href }: { name: string, href: string }) => {
  return (
    <Link href={href}>
      <a>{ name }</a>
    </Link>
  );
}

const Navbar = () => {
  const scrollYRef = useRef(0);
  const visibleRef = useRef(true);
  const [visible, setVisible] = useState(true);

  useEffect(() => {
    const onScroll = (event: Event) => {
      event.preventDefault();
      if ((window.scrollY < scrollYRef.current) != visibleRef.current) {
        visibleRef.current = !visibleRef.current;
        setVisible(x => !x);
      }
      scrollYRef.current = window.scrollY;
    }

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

  return (
    <div className={`${!visible && '-translate-y-full'} fixed flex w-full h-32 font-bold text-white transition-all`}>
      <NavbarLink name="home" href='/'/>
    </div>
  );
}
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

You could use the "latest ref" pattern (here via react-use's useLatest hook), which boxes the latest value of a state atom at each component update time, so you don't need to manage it manually, and you don't need it as a dependency for the hook. (I'd also grab useEvent from react-use if you end up using it.)

import React, { useState, useRef, useEffect } from "react";
import Link from "next/link";

// via https://github.com/streamich/react-use/blob/master/src/useLatest.ts
const useLatest = (value) => {
  const ref = useRef(value);
  ref.current = value;
  return ref;
};

const NavbarLink = ({ name, href }: { name: string; href: string }) => {
  return (
    <Link href={href}>
      <a>{name}</a>
    </Link>
  );
};

function useVisibleOnScrollUp(initial = true) {
  const scrollYRef = useRef(window.scrollY);
  const [visible, setVisible] = useState(initial);
  const latestVisibleRef = useLatest(visible);

  useEffect(() => {
    const onScroll = (event: Event) => {
      event.preventDefault();
      const currentVisible = latestVisibleRef.current;
      if (window.scrollY < scrollYRef.current != currentVisible) {
        setVisible((x) => !x);
      }
      scrollYRef.current = window.scrollY;
    };

    window.addEventListener("scroll", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
    };
  }, []);
  return visible;
}

const Navbar = () => {
  const visible = useVisibleOnScrollUp(true);
  return (
    <div
      className={`${
        !visible && "-translate-y-full"
      } fixed flex w-full h-32 font-bold text-white transition-all`}
    >
      <NavbarLink name="home" href="/" />
    </div>
  );
};
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda