新的react 钩子和状态,试图找出我的代码不工作的原因.

我有一个App.js文件和一个名为Menu.js的子组件.基本上,Menu.js包含一个菜单,如果变量isOpentrue,我想显示它,如果变量isOpenfalse,我想隐藏它.我在App.js上添加了父级功能,因为我还有另一个组件需要能够更新isOpen的状态,但该组件与我的问题无关.以下是相关代码:

App.js:

import Menu from "./components/Menu";
import { useState } from "react";

export default function App() {
  const [isOpen, setIsOpen] = useState(false);
  const toggleState = () => setIsOpen(!isOpen);
  console.log(isOpen); 
    // This will console log either true or false

  const menuBtn = document.querySelector(".hamburgermenu");
  const mobileMenu = document.querySelector(".mobilemenu");
    // These are elements on the child component, Menu.js

  if (isOpen) {
    menuBtn.classList.add("open");
    mobileMenu.style.zIndex = "5";
      // This should reveal the menu if the value of isOpen is true
  } else {
      menuBtn.classList.remove("open");
      mobileMenu.style.zIndex = "0";
        // This should hide the menu if the value of isOpen is false
  }

return (
  <div>
    <Menu togglestate={toggleState} /> 
      // Passing togglestate down to Menu.js as a prop
  </div>
  );
}

Menu.js:

export default function Menu(props) {
  return (
    <div>
      <div className="hamburgermenu" onClick={props.togglestate}>Stuff in here</div>
      // Clicking this div will toggle the value of isOpen between true and false
      <div className="mobilemenu">Stuff in here</div>
    </div>
  );
}

当我试图运行它时,我的整个应用程序都中断了,我在menuBtn.classList.remove("open");处得到了错误TypeError: Cannot read properties of null (reading 'classList')

我知道我的问题在于默认状态是false,所以它将首先try 运行else语句.然而,由于类open还没有添加到menuBtn元素中,因此没有要删除的open类,它正在出错.

我试图在原来的else语句中添加另一个嵌套的if/else语句,基本上是说if元素有一个名为open的类,删除它,如下所示:

  if (isOpen) {
    menuBtn.classList.add("open");
    mobileMenu.style.zIndex = "5";
  } else {
      if (menuBtn.classList.contains("open")) {
        menuBtn.classList.remove("open");
        mobileMenu.style.zIndex = "0";
      } else {
          mobileMenu.style.zIndex = "0";
      }
  }

我还try 完全脱离类,直接更改样式作为测试,如下所示:

if (menuOpen) {
  menuBtn.style.display = "block";
  mobileMenu.style.zIndex = "5";
} else {
  menuBtn.style.display = "none";
  mobileMenu.style.zIndex = "0";
}

但我在同一行有个错误,在menuBtn.style.display = "block";行有个错误

我知道这有点乱.我相信有更好的方法可以做到这一点,但我会用我所掌握的知识来做这件事.如果有更简单的方法,我愿意接受建议!

推荐答案

React的总体思路是不必直接用document.querySelector(".hamburgermenu")之类的东西处理DOM

您可以直接将setter函数setIsOpen传递到菜单函数中,而不是创建新函数toggleState,如下所示(以及当前打开状态)

<Menu isOpen={isOpen} togglestate={setIsOpen} />

然后,整个if-else条件可以简化为三元运算符,如下所示:

export default function Menu({ isOpen, togglestate }) {
    return (
        <>
            <div
                className={'hamburgermenu' + isOpen ? ' open' : ''}
                onClick={() => togglestate(!isOpen)}
            >
                // Clicking this div will toggle the value of isOpen between true and
                false
            </div>
            <div className="mobilemenu" style={{ zIndex: isOpen ? 5 : 1 }}>
                Stuff in here
            </div>
        </>
    );
}

Javascript相关问答推荐

jQuery s data()[storage object]在vanilla JavaScript中?'

从Node JS将对象数组中的数据插入Postgres表

如何在JavaScript文件中使用Json文件

我创建了一个创建对象的函数,我希望从该函数创建的对象具有唯一的键.我怎么能做到这一点?

使用Java脚本导入gltf场景并创建边界框

如何在文本字段中输入变量?

连接到游戏的玩家不会在浏览器在线游戏中呈现

在Reaction中的handleSubmit按钮内,useSelector值仍然为空

为什么这个.add.group({})在教程中运行得很好,但在我的游戏中就不行了?

是否可以在Photoshop CC中zoom 路径项?

自定义图表工具提示以仅显示Y值

无法重定向到Next.js中的动态URL

Django导入问题,无法导入我的应用程序,但我已在设置中安装了它

不协调嵌入图片

设置复选框根据选中状态输入选中值

如何在Web项目中同步语音合成和文本 colored颜色 更改

将Windows XP转换为原始数据以在html前端中显示

从客户端更新MongoDB数据库

在Java脚本的返回中创建变量是一种好的做法吗?

无法将bson类型转换为日期MongoDB