如何在 React 函数式组件中正确使用 useRef hook?
How to use useRef hook properly in react Functional Component?
我有一个 JavaScript 片段,我正在尝试在 React 中实现相同的片段。这是片段。
const nav = document.querySelector('.nav');
window.addEventListener('scroll', fixNav);
function fixNav() {
if (window.scrollY > nav.offsetHeight) {
nav.classList.add('active');
} else {
nav.classList.remove('active');
}
}
有关代码段的更多详细信息,请参阅此 codepen. When I scroll I'm just adding a class to the an element and removing when a certain condition is met using scroll eventListerner
. Here is how I tried in react with the help of this official documentation。
const Navbar = () => {
const navbar = useRef(null)
window.addEventListener('scroll', () => {
if (window.scrollY > navbar.current.offsetHeight + 550) {
navbar.current.classList.add('active');
}else{
navbar.current.classList.remove('active');
}
});
return (
<Fragment>
<nav id='navbar' className="nav" ref={navbar}>
<div className="container">
<h1 className="logo"><a href="/index.html"></a>My Website</h1>
<ul>
<li><a href="#" className="current">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
</nav>
{/* other elements */}
</Fragment>
)
}
错误
TypeError: Cannot read property 'offsetHeight' of null
因此,当我实际滚动并且满足条件时,我试图获取的元素 navbar
变为空。当 console.log 时,我可以在控制台中看到导航栏元素,同时也可以看到错误。我确定我错过了幕后的基本概念。
如果我试图在安装组件之前获取 DOM 元素,我必须使用 useEffect
来正确处理它。我是新手,无法使用 useEffect
钩子给它一个好的镜头。
您应该在 useEffect 挂钩中添加事件侦听器,以确保在为 ref 分配 dom 元素后访问它。
const Navbar = () => {
const navbar = useRef(null);
useEffect(()=>{
window.addEventListener("scroll", () => {
if(navbar.current!==null){
if (window.scrollY > navbar.current.offsetHeight + 550) {
navbar.current.classList.add("active");
} else {
navbar.current.classList.remove("active");
}
}
});
},[]);
return (
<Fragment>
<nav id="navbar" className="nav" ref={navbar}>
<div className="container">
<h1 className="logo">
<a href="/index.html"></a>My Website
</h1>
<ul>
<li>
<a href="#" className="current">
Home
</a>
</li>
<li>
<a href="#">About</a>
</li>
<li>
<a href="#">Services</a>
</li>
<li>
<a href="#">Contact</a>
</li>
</ul>
</div>
</nav>
{/* other elements */}
</Fragment>
);
};
我有一个 JavaScript 片段,我正在尝试在 React 中实现相同的片段。这是片段。
const nav = document.querySelector('.nav');
window.addEventListener('scroll', fixNav);
function fixNav() {
if (window.scrollY > nav.offsetHeight) {
nav.classList.add('active');
} else {
nav.classList.remove('active');
}
}
有关代码段的更多详细信息,请参阅此 codepen. When I scroll I'm just adding a class to the an element and removing when a certain condition is met using scroll eventListerner
. Here is how I tried in react with the help of this official documentation。
const Navbar = () => {
const navbar = useRef(null)
window.addEventListener('scroll', () => {
if (window.scrollY > navbar.current.offsetHeight + 550) {
navbar.current.classList.add('active');
}else{
navbar.current.classList.remove('active');
}
});
return (
<Fragment>
<nav id='navbar' className="nav" ref={navbar}>
<div className="container">
<h1 className="logo"><a href="/index.html"></a>My Website</h1>
<ul>
<li><a href="#" className="current">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
</nav>
{/* other elements */}
</Fragment>
)
}
错误
TypeError: Cannot read property 'offsetHeight' of null
因此,当我实际滚动并且满足条件时,我试图获取的元素 navbar
变为空。当 console.log 时,我可以在控制台中看到导航栏元素,同时也可以看到错误。我确定我错过了幕后的基本概念。
如果我试图在安装组件之前获取 DOM 元素,我必须使用 useEffect
来正确处理它。我是新手,无法使用 useEffect
钩子给它一个好的镜头。
您应该在 useEffect 挂钩中添加事件侦听器,以确保在为 ref 分配 dom 元素后访问它。
const Navbar = () => {
const navbar = useRef(null);
useEffect(()=>{
window.addEventListener("scroll", () => {
if(navbar.current!==null){
if (window.scrollY > navbar.current.offsetHeight + 550) {
navbar.current.classList.add("active");
} else {
navbar.current.classList.remove("active");
}
}
});
},[]);
return (
<Fragment>
<nav id="navbar" className="nav" ref={navbar}>
<div className="container">
<h1 className="logo">
<a href="/index.html"></a>My Website
</h1>
<ul>
<li>
<a href="#" className="current">
Home
</a>
</li>
<li>
<a href="#">About</a>
</li>
<li>
<a href="#">Services</a>
</li>
<li>
<a href="#">Contact</a>
</li>
</ul>
</div>
</nav>
{/* other elements */}
</Fragment>
);
};