我已经创建了一个有两个不同导航栏的Next js应用程序.一个导航栏将用于家庭,另一个将用于其他路由.所以在我的header.js文件中,我有一组代码-

import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import HomeNavbar from "./Navbar/HomeNavbar";
import Navbar from "./Navbar/Navbar";

function Header() {
  const router = useRouter();
  const [isHome, setIsHome] = useState(false);

  useEffect(() => {
    if (router.pathname === "/") {
      setIsHome(true);
    } else {
      setIsHome(false);
    }
  }, [router.pathname]);

  return <>{isHome ? <HomeNavbar /> : <Navbar />}</>;
}

export default Header;

因此,当我在家乡路由上时,HomeNavBar正在被使用,在HomeNavBar组件中,我有一组代码,如下所示-

useEffect(() => {
    window.onscroll = function() {
      const maxHeight = 192;
      const minHeight = 40;
      let pixel = window.scrollY;
      let pixelPosition =  maxHeight - pixel;
      pixelPosition = pixelPosition > maxHeight ? maxHeight : pixelPosition;
      pixelPosition = pixelPosition < minHeight ? minHeight : pixelPosition;
      document.getElementById("brandmark").style.cssText = `
        height: ${pixelPosition}px; 
        width: auto;
      `;
    }
  }, [])

这只是一个基本函数,我正在对包含id="brandmark"的元素执行某些操作 但是,当我更改到/关于的路径时,函数仍然在运行,并且我收到一个错误,因为具有该id的元素在关于页面或任何其他路径上不可用. 我怎么才能解决这个问题呢?

以下是错误消息- 未处理的运行时错误 TypeError:无法读取Null的属性(正在读取‘style’)

components\UI\Navbar\HomeNavbar.js (40:43) @ window.onscroll

  38 | pixelPosition = pixelPosition > maxHeight ? maxHeight : pixelPosition;
  39 | pixelPosition = pixelPosition < minHeight ? minHeight : pixelPosition;
> 40 | document.getElementById("brandmark").style.cssText = `
     |                                     ^
  41 |   height: ${pixelPosition}px; 
  42 |   width: auto;
  43 | `;

推荐答案

当组件卸载时,没有清除功能删除onscroll监听程序.这就是为什么您会继续看到调用的事件回调.

设置全局onscroll回调也被认为是反模式的,因为这将覆盖任何现有的值.最好使用addEventListenerremoveEventListener函数.

添加清除函数以删除事件侦听器.

useEffect(() => {
  const scrollHandler = function() {
    const maxHeight = 192;
    const minHeight = 40;
    let pixel = window.scrollY;
    let pixelPosition =  maxHeight - pixel;
    pixelPosition = pixelPosition > maxHeight ? maxHeight : pixelPosition;
    pixelPosition = pixelPosition < minHeight ? minHeight : pixelPosition;
    document.getElementById("brandmark").style.cssText = `
      height: ${pixelPosition}px; 
      width: auto;
    `;
  }

  window.addEventListener("scroll", scrollHandler, { passive: true });
  return () => {
    window.removeEventListener("scroll", scrollHandler, { passive: true });
  };
}, []);

如果id为"brandmark"的元素有时不可用,您应该使用NULL-CHECK/GARD-子句来防止意外的未定义/NULL属性访问.在这里使用可选的链运算符.

document.getElementById("brandmark")?.style.cssText = `
  height: ${pixelPosition}px; 
  width: auto;
`;

或使用NULL-CHECK/Guard-子句

document.getElementById("brandmark") && 
document.getElementById("brandmark").style.cssText = `
  height: ${pixelPosition}px; 
  width: auto;
`;

Reactjs相关问答推荐

父组件更新后不重新呈现子组件

有没有方法覆盖NextJS 14中的布局?

为什么我的标签在Redux API中不能正常工作?

在Reaction中单击时,按钮未按预期工作

将对象添加到集合中的数组时的no_id字段

有没有办法将MUI网格元素与Flex-Start对齐?

如何通过reactjs正确显示记录

useRef()的钩子调用无效

useEffect不重新渲染

如果我使用 formik,如何在嵌套对象中写入正确的值?

react 本机屏幕转换

我发送的 prop 的值不会改变.如果成功登录,导航栏中的 prop 必须为 true.我从后端得到 200 ok

在React Router 6中,在路由渲染后更新路由数据

如何读取 null 的属性?

如何使用 redux 和 react-plotly.js

如何在 React Native 中更新跨屏幕呈现的上下文状态变量?

用 jest 测试包裹在 redux 和 router 中的组件

如何将值从下拉列表传递到 select 上的输入?响应式JS

如何使用 cypress 获取 MUI TextField 的输入值?

无法有条件地更新useEffect中的setState