skip to Main Content

I was trying to convert my class-based component to function based component, which I wrote some while when I was learning REACT, while converting this, I got an error that isOpen is not the function which I kinda dint get as I defined it as a state and called in handleToggle(), which is then being called at the logo of my component.

import React, { useState, useEffect } from "react";
import logo from "../images/logo.svg";
import { FaAlignRight } from "react-icons/fa";
import { Link } from "react-router-dom";
import Badge from '@mui/material/Badge';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';

export default function Navbar(){

  const [anchorEl, setAnchorEl] = useState(null);
  const open = Boolean(anchorEl);
  const handleClick = (event) => {
    setAnchorEl(event.currentTarget);
  };
  const handleClose = () => {
    setAnchorEl(null);
  };
   
  const [isOpen, setIsOpen] = useState(null);
  
 useEffect(() =>{
  handleToggle();
 });
  
  // state = {
  //   isOpen: false,
  // };
  const handleToggle = () => {
    setIsOpen(isOpen() );
  };



    return (
      <nav className="navbar">
        <div className="nav-center">
          <div className="nav-header">
            <Link to="/">
              <img src={logo} alt="Beach Resort" />
            </Link>
            <button
              type="button"
              className="nav-btn"
              onClick={handleToggle}
            >
              <FaAlignRight className="nav-icon" />
            </button>
          </div>
          <ul
            className={isOpen ? "nav-links show-nav" : "nav-links"}
          >
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/rooms">Rooms</Link>
            </li>
          </ul>
          <Badge badgeContent={4} color="primary" 
              id="basic-button"
              aria-controls={open ? 'basic-menu' : undefined}
              aria-haspopup="true"
              aria-expanded={open ? 'true' : undefined}
              onClick={handleClick}
          >
            <i className="fa-solid fa-cart-shopping text-light"
              style={{ fontSize: 25, cursor: "pointer" }}
            ></i>
          </Badge>
        </div>
        <Menu
        id="basic-menu"
        anchorEl={anchorEl}
        open={open}
        onClose={handleClose}
        MenuListProps={{
          'aria-labelledby': 'basic-button',
        }}
      >
        <MenuItem onClick={handleClose}>Profile</MenuItem>
        <MenuItem onClick={handleClose}>My account</MenuItem>
        <MenuItem onClick={handleClose}>Logout</MenuItem>
      </Menu>
      </nav>
    );
  }

EVERY PIECE OF ADVICE WILL BE APPRECIATED

2

Answers


  1. isOpen is a value, not a function. Try setIsOpen(p => !p)

    Login or Signup to reply.
  2. useState returns an array with two things: a value that is stored in state, and a function to update it. If you call const [isOpen, setIsOpen] = useState(null), isOpen is your value (originally set as null) and setIsOpen is a function to update it.

    When you write const handleToggle = () => { setIsOpen(isOpen() ) }, you’re trying to call a null value, which is impossible because it’s not a function. That’s what the error message is telling you.

    Given you want to toggle the value for isOpen, what you should do instead is declare isOpen as a boolean, and call setIsOpen with the opposite of isOpen:

    const [isOpen, setIsOpen] = useState(false);  // <= set this originally to false
    
    const handleToggle = () => {
      setIsOpen(!isOpen); // <= this will set isOpen as true when it is false, and false when it is true
    };
    

    However, if you call handleToggle inside a useEffect with no dependency array, like you’re doing, it will be called every time there is a rerender, which is probably not what you want. You most likely want to call this in response to a user interaction – so in response to an HTML element event (like onClick). Otherwise you should refactor your code to add the necessary dependencies to useEffect.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search