Home > Blockchain >  React says too many render
React says too many render

Time:02-06

The renderDialogue function should render Dialogue when window size is less than 654 other wise it should update the state of expandMenu to false. But react says to many re render . How to solve this?

const [expandMenu, setExpandMenu] = useState(false); 



  const handleOpenMenu = () => {
    setExpandMenu(!expandMenu);
  };

const renderDialogue = () => {
    if (window.innerWidth < 654) {
      return (
        <Dialog
          open={expandMenu}
          handler={() => handleOpenMenu()}
          size={"xl"}
          className={"bg-transparent shadow-none "}
        >
          <DialogBody>
            <div className={"relative"}>
              <img
                src={"/imgFolder2/cloud.webp"}
                className={"h-full float-center"}
              />
              <ul className="flex flex-col justify-center h-[75%] gap-5 text-2xl text-center absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] w-[55%]">
                {NavItems()}
              </ul>
            </div>
          </DialogBody>
        </Dialog>
      );
    } else {
      setExpandMenu(false);
      return <> </>;
    }
  };

Here is the NavItems function : It just iterates through an array of links


const NavItems = () => {
    return paths.map((path, idx) => (
      <li key={idx}>
        <Link
          href={getPath(idx)}
          className={`text-black block ${
            isSelectedPath(getName(idx, true))
              ? "border-b-4 border-buttonBG"
              : ""
          }`}
          onClick={() => {
            if (window.innerWidth < 654) setExpandMenu(!expandMenu);
          }}
        >
          {getName(idx)}
        </Link>
      </li>
    ));
  };

CodePudding user response:

First of all, your component will never rerender when the window size change. This means att your if-statement where you display something depening on the window width, will only fire on first render. Which probably is fine, but not recommended.

Secondly, your error to many rerenders is because you invoke setExpandMenu directly in your component. Each time you update your expandMenu state this component will rerender, and then you update it again, so it will rerender again. See the infinte loop here?

Below is a working example of what you want, including update on window resize. I've added comments to explain what is happening:

const [expandMenu, setExpandMenu] = useState(false); 
const [windowWidth, setWindowWidth] = useState(0)


   useEffect(() => { // This will update your state depending on your window size
    function updateSize() {
    setWindowWidth(window.innerWidth)
      

    }
    window.addEventListener('resize', updateSize);
    updateSize();
    return () => window.removeEventListener('resize', updateSize);
  }, []);

  const handleOpenMenu = () => {
    setExpandMenu(!expandMenu);
  };

const renderDialogue = () => {

    
    if (windowWidth > 654 || expandMenu) {
      return (
        <Dialog
          open={expandMenu}
          handler={() => handleOpenMenu()}
          size={"xl"}
          className={"bg-transparent shadow-none "}
        >
          <DialogBody>
            <div className={"relative"}>
              <img
                src={"/imgFolder2/cloud.webp"}
                className={"h-full float-center"}
              />
              <ul className="flex flex-col justify-center h-[75%] gap-5 text-2xl text-center absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] w-[55%]">
                {NavItems()}
              </ul>
            </div>
          </DialogBody>
        </Dialog>
      );
    } else {
      // setExpandMenu(false); <--- This line is causing rerenders: Remove it!
      return <> </>;
    }

  • Related