Javascript 错误:无效的钩子调用。钩子只能在函数组件的主体内部调用。使用React.js时
我得到一个错误: 错误:无效的钩子调用。钩子只能在函数组件的主体内部调用 我的钩子代码:Javascript 错误:无效的钩子调用。钩子只能在函数组件的主体内部调用。使用React.js时,javascript,reactjs,Javascript,Reactjs,我得到一个错误: 错误:无效的钩子调用。钩子只能在函数组件的主体内部调用 我的钩子代码: function WidthAndHeight() { const [width, setWidth] = React.useState(window.innerWidth); const [height, setHeight] = React.useState(window.innerHeight); React.useEffect(() => { window.addEven
function WidthAndHeight() {
const [width, setWidth] = React.useState(window.innerWidth);
const [height, setHeight] = React.useState(window.innerHeight);
React.useEffect(() => {
window.addEventListener("resize", updateWidthAndHeight);
return () => window.removeEventListener("resize", updateWidthAndHeight);
});
const updateWidthAndHeight = () => {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
};
return (
{
"width": width,
"height": height
}
);
}
当我在onMouseEnter
上调用它时,会出现以下错误:
class MegaMenu extends React.Component {
public render() {
return (
<div className={styles.MegaMenu}>
<div className={styles["menu-container"]}>
<div className={styles.menu}>
<MenuList Options={menus} />
</div>
</div>
</div>
)
}
}
const MenuList = (props: IMenuListProps) => {
const handleOnMouseEnter = () => {
if (WidthAndHeight().width > 943) {
console.log("WidthAndHeight().width")
}
}
return (
<ul onMouseEnter={handleOnMouseEnter}>
{
props.Options.map((Option: IMenu, index: number) => (
<li key={index} className={(Option.subitem && Option.subitem.length > 0) ? styles["menu-dropdown-icon"] : styles["normal-sub"]} onMouseEnter={handleOnMouseEnter}>
<a href={Option.link}>{Option.name}</a>
{/* Base Case */}
{
(Option.subitem && Option.subitem.length > 0) &&
<MenuList Options={Option.subitem} />
}
</li>
))
}
</ul>
)
}
class MegaMenu扩展了React.Component{
公共渲染(){
返回(
)
}
}
const MenuList=(props:IMenuListProps)=>{
常量handleOnMouseEnter=()=>{
如果(宽度和高度().宽度>943){
console.log(“宽度和高度().width”)
}
}
返回(
{
props.Options.map((选项:IMenu,索引:number)=>(
- 0)?样式[“菜单下拉图标”]:样式[“普通子”]}onMouseCenter={handleOnMouseEnter}>
{/*基本情况*/}
{
(Option.subitem&&Option.subitem.length>0)&&
}
))
}
)
}
有谁能指导我如何解决这个问题吗?您需要使用自定义挂钩来完成您的工作-
function useWidthAndHeight() {
const [width, setWidth] = React.useState(window.innerWidth);
const [height, setHeight] = React.useState(window.innerHeight);
React.useEffect(() => {
window.addEventListener("resize", updateWidthAndHeight);
return () => window.removeEventListener("resize", updateWidthAndHeight);
});
const updateWidthAndHeight = () => {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
};
const windowData = {
"width": width,
"height": height
}
return (
windowData
);
}
export default function useWidthAndHeight
然后你可以像这样导入它
从“/customHook.js”导入useWidthAndWIndow
并将其用作功能组件内部的挂钩
const windowData=useWidthAndWIndow()
您需要使用自定义钩子来完成您正在做的事情-
function useWidthAndHeight() {
const [width, setWidth] = React.useState(window.innerWidth);
const [height, setHeight] = React.useState(window.innerHeight);
React.useEffect(() => {
window.addEventListener("resize", updateWidthAndHeight);
return () => window.removeEventListener("resize", updateWidthAndHeight);
});
const updateWidthAndHeight = () => {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
};
const windowData = {
"width": width,
"height": height
}
return (
windowData
);
}
export default function useWidthAndHeight
然后你可以像这样导入它
从“/customHook.js”导入useWidthAndWIndow
并将其用作功能组件内部的挂钩
const windowData=useWidthAndWIndow()
您已经创建了自定义挂钩,但使用错误。下面的代码应该可以工作
const MenuList = (props: IMenuListProps) => {
const { width, height } = WidthAndHeight(); // --> call hook in component function body, not in eventhandler!
const handleOnMouseEnter = () => {
if (width > 943) {
//...
}
}
return (
<ul onMouseEnter={handleOnMouseEnter}>
{
props.Options.map((Option: IMenu, index: number) => (
<li key={index} className={(Option.subitem && Option.subitem.length > 0) ? styles["menu-dropdown-icon"] : styles["normal-sub"]} onMouseEnter={handleOnMouseEnter}>
<a href={Option.link}>{Option.name}</a>
{/* Base Case */}
{
(Option.subitem && Option.subitem.length > 0) &&
<MenuList Options={Option.subitem} />
}
</li>
))
}
</ul>
)
}
const MenuList=(props:IMenuListProps)=>{
const{width,height}=widthandheath();//-->在组件函数体中调用钩子,而不是在eventhandler中!
常量handleOnMouseEnter=()=>{
如果(宽度>943){
//...
}
}
返回(
{
props.Options.map((选项:IMenu,索引:number)=>(
- 0)?样式[“菜单下拉图标”]:样式[“普通子”]}onMouseCenter={handleOnMouseEnter}>
{/*基本情况*/}
{
(Option.subitem&&Option.subitem.length>0)&&
}
))
}
)
}
您已经创建了自定义挂钩,但使用错误。下面的代码应该可以工作
const MenuList = (props: IMenuListProps) => {
const { width, height } = WidthAndHeight(); // --> call hook in component function body, not in eventhandler!
const handleOnMouseEnter = () => {
if (width > 943) {
//...
}
}
return (
<ul onMouseEnter={handleOnMouseEnter}>
{
props.Options.map((Option: IMenu, index: number) => (
<li key={index} className={(Option.subitem && Option.subitem.length > 0) ? styles["menu-dropdown-icon"] : styles["normal-sub"]} onMouseEnter={handleOnMouseEnter}>
<a href={Option.link}>{Option.name}</a>
{/* Base Case */}
{
(Option.subitem && Option.subitem.length > 0) &&
<MenuList Options={Option.subitem} />
}
</li>
))
}
</ul>
)
}
const MenuList=(props:IMenuListProps)=>{
const{width,height}=widthandheath();//-->在组件函数体中调用钩子,而不是在eventhandler中!
常量handleOnMouseEnter=()=>{
如果(宽度>943){
//...
}
}
返回(
{
props.Options.map((选项:IMenu,索引:number)=>(
- 0)?样式[“菜单下拉图标”]:样式[“普通子”]}onMouseCenter={handleOnMouseEnter}>
{/*基本情况*/}
{
(Option.subitem&&Option.subitem.length>0)&&
}
))
}
)
}
您应该为您要做的事情制作自己的定制挂钩。既然你没有从那门课上归还任何东西它不是一种化学成分。您的React组件只能用作JSX来呈现某些内容。它不能用来解决一些逻辑问题。@AtinSingh,你能帮我怎么做吗!!我对React很陌生。我添加了它作为答案。@Milind如果你是React新手,我建议:了解,也熟悉React.Component
,然后了解。你应该为你要做的事情制作自己的自定义钩子。既然你没有从那门课上归还任何东西它不是一种化学成分。您的React组件只能用作JSX来呈现某些内容。它不能用来解决一些逻辑问题。@AtinSingh,你能帮我怎么做吗!!我对React很陌生。我添加了它作为答案。@Milind如果你是React新手,我建议:了解,也要熟悉React.Component
,然后了解。I guest你必须调用useWidthAndHeight()
,它将返回{windowData}及其更新。但他实现了自定义挂钩,但是用错了地方。请参阅下面的答案。@RafaelHovsepyan很抱歉,自定义挂钩是否可以像react组件一样以大写字母开头?@RafaelHovsepyan根据react文档,它说我是否必须命名以“use”开头的自定义挂钩?请吧。这项公约非常重要。如果没有它,我们将无法自动检查是否违反了钩子规则,因为我们无法判断某个函数是否包含对其内部钩子的调用。
这只是一种约定,您甚至不必使用“use”前缀。我想您必须调用useWidthAndHeight()
,它将返回{windowData}但是他实现了自定义钩子,但是在错误的地方使用了它。请参阅下面的答案。@RafaelHovsepyan很抱歉,自定义挂钩是否可以像react组件一样以大写字母开头?@RafaelHovsepyan根据react文档,它说我是否必须命名以“use”开头的自定义挂钩?请吧。这项公约非常重要。如果没有它,我们将无法自动检查是否违反了钩子规则,因为我们无法判断某个函数是否包含对其内部钩子的调用。
这只是一种约定,您甚至不需要使用“use”前缀。