Reputation: 1955
I am getting an error:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
My Hook Code:
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
}
);
}
When I call it on onMouseEnter
it gives the error below:
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>
)
}
Can anyone guide me on how I can solve this issue?
Upvotes: 0
Views: 712
Reputation: 781
You have already created custom hook, but used it wrong. The code below should work.
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>
)
}
Upvotes: 2
Reputation: 3690
You need to use custom hook for what you are doing -
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
Then you can import it like this.
import useWidthAndWIndow from "./customHook.js"
And use it as a hook inside your functional component
const windowData = useWidthAndWIndow()
Upvotes: 0