TypeError: Cannot read properties of null (reading 'classList') React
TypeError: Cannot read properties of null (reading 'classList') React
我正在滚动这个 header,我想将背景更改为不同的颜色。
navbar
变量 returns 始终为 null。为什么会这样?我怎样才能做到这一点?
transform:translateY
仅用于滚动时的小动画。
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
您正试图在导航栏呈现之前获取它。这就是您的变量为空的原因。尝试使用Ref to access a node element in React. 会对你有所帮助。
你正在做我想称之为“反对 React 方式”的事情。要访问导航栏元素,您应该使用 useRef
挂钩。这将使您在整个组件生命周期中轻松引用该元素。
除此之外,还有一些问题需要注意:
scrolled
变量未与 useState
一起使用
- 您的滚动侦听器未在
useEffect
中设置。现在,您的代码会在组件的每次重新渲染时设置一个新的侦听器。您只想设置一次。
- 您的滚动侦听器未被清理。
我对代码做了一些更改,希望能为您解决这个问题。
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;
你没有以反应的方式去做。有很多方法可以做到这一点,其中一个是您可以使用 useState 钩子来跟踪滚动并通过这种方式在 jsx 中根据高度变化更新它,您可以只使用三元运算符来更改类名,例如
<div className = {scrolled ? "color-nav" : "something" }
我正在滚动这个 header,我想将背景更改为不同的颜色。
navbar
变量 returns 始终为 null。为什么会这样?我怎样才能做到这一点?
transform:translateY
仅用于滚动时的小动画。
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
您正试图在导航栏呈现之前获取它。这就是您的变量为空的原因。尝试使用Ref to access a node element in React.
你正在做我想称之为“反对 React 方式”的事情。要访问导航栏元素,您应该使用 useRef
挂钩。这将使您在整个组件生命周期中轻松引用该元素。
除此之外,还有一些问题需要注意:
scrolled
变量未与useState
一起使用
- 您的滚动侦听器未在
useEffect
中设置。现在,您的代码会在组件的每次重新渲染时设置一个新的侦听器。您只想设置一次。 - 您的滚动侦听器未被清理。
我对代码做了一些更改,希望能为您解决这个问题。
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;
你没有以反应的方式去做。有很多方法可以做到这一点,其中一个是您可以使用 useState 钩子来跟踪滚动并通过这种方式在 jsx 中根据高度变化更新它,您可以只使用三元运算符来更改类名,例如
<div className = {scrolled ? "color-nav" : "something" }