Tengo este encabezado que, al desplazarse, quiero cambiar el fondo a un color diferente. La variable de la navbar
de navegación devuelve nulo siempre. ¿Por que es esto entonces? ¿Cómo puedo hacer eso? El transform:translateY
es solo para una pequeña animación en el desplazamiento.
import React from 'react' import { Navbar, Container, Nav } from 'react-bootstrap' import { LinkContainer } from 'react-router-bootstrap' const Header = () => { const navbar = document.getElementById("navbar"); let scrolled = false; window.onscroll = function () { if (document.body.scrollTop >= 200 || document.documentElement.scrollTop >= 200) { navbar.classList.add('color-nav'); if (!scrolled) { navbar.style.transform = 'translateY(-70px)' } setTimeout(function () { navbar.style.transform = 'translateY(0px)' scrolled = true }, 200) } else { navbar.classList.remove('color-nav'); scrolled = false } }; return ( <div id='navbar' > <Navbar fixed="top" className='navbar' collapseOnSelect expand="lg" > <Container> <LinkContainer to='/'> <Navbar.Brand className='logo' >Logo</Navbar.Brand> </LinkContainer> <Navbar.Toggle aria-controls="responsive-navbar-nav" /> <Navbar.Collapse id="responsive-navbar-nav"> <Nav className="me-auto"> <LinkContainer to='/services'> <Nav.Link className='links'>Services</Nav.Link> </LinkContainer> </Nav> <Nav> <LinkContainer to='/login'> <Nav.Link className='links'>Login</Nav.Link> </LinkContainer> <LinkContainer to='/signup'> <Nav.Link className='links'> Sign Up </Nav.Link> </LinkContainer> </Nav> </Navbar.Collapse> </Container> </Navbar> </div > ) } export default Header
Estás haciendo las cosas en lo que me gustaría llamar, "en contra de la forma React". Para acceder al elemento de la barra de navegación, debe utilizar el useRef
. Esto le dará una referencia fácil a ese elemento a través del ciclo de vida de los componentes.
Además de eso, hay algunos otros problemas que deben ser atendidos:
scrolled
no se usa con useState
useEffect
. En este momento, su código establecería un nuevo oyente en cada nueva representación de su componente. Solo desea configurarlo una vez.He realizado algunos cambios en el código que espero solucionen este problema.
import React, { useState, useRef, useEffect } from "react"; import { Navbar, Container, Nav } from "react-bootstrap"; import { LinkContainer } from "react-router-bootstrap"; const Header = () => { const [scrolled, setScrolled] = useState(false); const navRef = useRef(); useEffect(() => { const handleScroll = () => { if ( document.body.scrollTop >= 200 || document.documentElement.scrollTop >= 200 ) { navRef.current.classList.add("color-nav"); if (!scrolled) { navRef.current.style.transform = "translateY(-70px)"; } setTimeout(function () { navRef.current.style.transform = "translateY(0px)"; setScrolled(true); }, 200); } else { navRef.current.classList.remove("color-nav"); setScrolled(false); } }; window.addEventListener("scroll", handleScroll); return () => { window.removeEventListener("scroll", handleScroll); }; }, []); return ( <div id="navbar" ref={navRef}> <Navbar fixed="top" className="navbar" collapseOnSelect expand="lg"> <Container> <LinkContainer to="/"> <Navbar.Brand className="logo">Logo</Navbar.Brand> </LinkContainer> <Navbar.Toggle aria-controls="responsive-navbar-nav" /> <Navbar.Collapse id="responsive-navbar-nav"> <Nav className="me-auto"> <LinkContainer to="/services"> <Nav.Link className="links">Services</Nav.Link> </LinkContainer> </Nav> <Nav> <LinkContainer to="/login"> <Nav.Link className="links">Login</Nav.Link> </LinkContainer> <LinkContainer to="/signup"> <Nav.Link className="links">Sign Up</Nav.Link> </LinkContainer> </Nav> </Navbar.Collapse> </Container> </Navbar> </div> ); }; export default Header;
No lo estás haciendo de manera reactiva. hay muchas maneras en las que podría hacer esto, uno de ellos es que puede usar el gancho useState para mantener el seguimiento del desplazamiento y actualizarlo en el cambio de altura de esta manera en jsx, puede usar el operador ternario para cambiar el nombre de clase como
<div className = {scrolled ? "color-nav" : "something" }
Está intentando obtener la barra de navegación antes de que se represente. Es por eso que su variable es nula. Intente usar Ref para acceder a un elemento de nodo en React. Las respuestas aquí pueden ser útiles para usted.