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



新的React钩子和状态,试图找出为什么我的代码不工作。

我有一个App.js文件和一个名为Menu.js的子组件。本质上,Menu.js包含一个菜单,我想显示一个名为isOpen的变量是否为true,并隐藏isOpen是否为false。我已经在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>
);
}

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

知道我的问题在于默认状态是false,因此它将首先尝试运行else语句。但是,因为类open还没有添加到menuBtn元素中,所以没有open类可以删除,所以它出错了。

我试图在原来的else语句中添加另一个嵌套的if/else语句,基本上是说如果元素有一个叫做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";
}
}

我也试过完全远离类,只是直接改变样式作为测试,像这样:

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,直接将设置函数setIsOpen传递给菜单函数,如下所示(连同当前打开状态)

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

相关内容

  • 没有找到相关文章

最新更新