React - 从子组件更新状态,然后根据状态做一些事情
React - Updating State From a Child Component, Then Doing Something Based on State
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>
);
}
当我尝试 运行 时,我的整个应用程序崩溃了,我在 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>
</>
);
}
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>
);
}
当我尝试 运行 时,我的整个应用程序崩溃了,我在 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")
无需创建新函数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>
</>
);
}