React - 从子组件更新状态,然后根据状态做一些事情

React - Updating State From a Child Component, Then Doing Something Based on State

React 钩子和状态的新手,试图弄清楚为什么我的代码不起作用。

我有一个 App.js 文件和一个名为 Menu.js 的子组件。本质上,Menu.js 包含一个菜单,我想在名为 isOpen 的变量为 true 时显示该菜单,如果 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,所以它会先尝试运行然后else陈述。但是,因为 class open 还没有添加到 menuBtn 元素,所以没有 open class 可以删除,它会出错。

我试图在原始 else 语句中添加另一个嵌套的 if/else 语句,基本上是说 if 元素具有 class称为 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";
      }
  }

我也试过完全放弃 classes 并直接更改样式作为测试,如下所示:

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

但是我仍然在同一行出错,TypeError: Cannot read properties of null (reading 'style')menuBtn.style.display = "block";

我知道这有点乱。我敢肯定有更好的方法可以做到这一点,但这是我将利用我所拥有的知识去做的方式。如果有更简单的方法,我愿意接受建议!

React 中的一般想法是不必直接使用 document.querySelector(".hamburgermenu")

之类的东西来处理 DOM

无需创建新函数toggleState,您可以直接将setter函数setIsOpen传递到Menu函数中,如下所示(连同当前打开状态)

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