Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

111
Visualizações
Sticky header with hide and show on scroll

I have a navbar with two part (navbarTop and navbarBottom); navbarTop will shown when the scrollY is bigger than 110 and the navbarbottom will shown when the user scroll up, but my problem is that each component will be re-called after each scroll, even scrolling down, or when the navbottom already exist and the user scroll up and it's still keep calling the component. here is the code:

const Navbar: FC = () => {

const [stickyHeader, setStickyHeader] = useState(false);
const [stickyMenu, setStickyMenu] = useState(false);

console.log('navbar')

const [y, setY] = useState(null);
const handleNavigation = useCallback(
    (e) => {
        const window = e.currentTarget;
        if (!stickyMenu) {
            if (y > window.scrollY) {
                setStickyMenu(true)
                // console.log("scrolling up");
            }
        }
        if (!stickyHeader) {
            if (window.scrollY >= 110) {
                setStickyHeader(true);
            }
        }
        if (stickyHeader) {
            if (window.scrollY <= 110) {
                setStickyHeader(false);
            }
        }
        if (stickyMenu) {
            if (y < window.scrollY) {
                setStickyMenu(false)
                // console.log("scrolling down");
            }
        }

        setY(window.scrollY);
    },
    [y, stickyMenu,stickyHeader]
);


useEffect(() => {
    window.addEventListener("scroll", handleNavigation);

    return () => {
        window.removeEventListener("scroll", handleNavigation);
    };
}, [handleNavigation, stickyMenu]);



return (
    <>
        <div className={s.root}>

            {stickyHeader === false ? (
                <div className='hidden xl:block md:w-auto'>
                    <NavbarTop sticky={false}/>
                    <NavbarBottom
                        sticky={false}/>
                </div>
            ) : (
                <div className='absolute hidden xl:block md:w-auto'>
                    <NavbarTop sticky={true}/>
                    {stickyMenu &&
                        <NavbarBottom sticky={true}/>
                    }
                </div>
            )}

            <SmallNav/>
        </div>
    </>

)

} export default Navbar

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

In fact, I did not quite understand your question. You said that each component is re-called after each scroll. Of course it will be re-called, right?

Whenever you scroll, you change the stickyHeader or stickyMenu. React listens for the state change and re-renders the component. This is how React works.

I see that you're using tailwindcss.

You can use a useMemo to listen to the state and then return the appropriate class based on the different state states. This way you avoid having to create DOM nodes over and over again. I don't know if this would help you or not. I hope this will help you.

const Navbar: FC = () => {
    const [stickyHeader, setStickyHeader] = useState(false);
    const [stickyMenu, setStickyMenu] = useState(false);
    // console.log('navbar');

    const [y, setY] = useState(null);
    const handleNavigation = useCallback(
        (e) => {
            const window = e.currentTarget;
            if (!stickyMenu) {
                if (y > window.scrollY) {
                    setStickyMenu(true);
                    // console.log("scrolling up");
                }
            }
            if (!stickyHeader) {
                if (window.scrollY >= 110) {
                    setStickyHeader(true);
                }
            }
            if (stickyHeader) {
                if (window.scrollY <= 110) {
                    setStickyHeader(false);
                }
            }
            if (stickyMenu) {
                if (y < window.scrollY) {
                    setStickyMenu(false);
                    // console.log("scrolling down");
                }
            }

            setY(window.scrollY);
        },
        [y, stickyMenu, stickyHeader],
    );

    useEffect(() => {
        window.addEventListener('scroll', handleNavigation);

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

    const stickyClassName = useMemo(() => {
        if (stickyHeader) {
            return 'sticky top-0 xl:block md:w-auto';
        }
        return 'xl:block md:w-auto';
    }, [stickyHeader]);

    return (
        <div className="test" style={{ height: 2000 }}>
            <div className={stickyClassName}>
                <NavbarTop sticky={stickyHeader} />
                {stickyMenu && <NavbarBottom sticky={stickyHeader} />}
            </div>
            <div>SmallNav</div>
        </div>
    );
};

export default Navbar;
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda