繁体   English   中英

如何在反应功能组件中正确使用 useRef 挂钩?

[英]How to use useRef hook properly in react Functional Component?

我有一个 JavaScript 片段,我正在尝试在反应中实现相同的功能。 这是片段。

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 当我滚动时,我只是将 class 添加到元素并在满足特定条件时使用scroll eventListerner 以下是我在此官方文档的帮助下尝试做出反应的方式。

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正在获取 null。 当 console.log 和错误同时出现时,我可以在控制台中看到导航栏元素。 我确定我在幕后遗漏了一个基本概念。

如果我试图在组件安装之前获取 DOM 元素,我必须使用useEffect来正确处理它。 我是新来的反应,无法使用useEffect钩子给它一个很好的机会。

您应该在 useEffect 挂钩中添加事件侦听器,以确保您在分配给 dom 元素后访问 ref。

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>
  );
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM