0

I am trying to redirect to another page when clicking on an item inside of a dropdown, on my sidenav. I get redirected as usual to the page the first time without any errors, however, when I click on the same item, or another from a different dropdown again, it throws this error:

Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.

I have created an array that stores all of the necessary information as props taken from another component, which can be seen here:

Taken from:

<SidenavDropdown
  sidenavButtonName="Service 0.5GB"
  sidenavItemNames={[
    "Console",
    "File Manager",
    "Remote Access",
    "Configuration",
    "Subusers",
  ]}
  sidenavItemLinks={[
    "/console",
    "/files",
    "/remote",
    "/configure",
    "/subusers",
  ]}

Given to rows in my SidenavDropdown:

  const rows = [];
  for (let i = 0; i < props.sidenavItemNames.length; i++) {
    rows.push(
      <DropdownItem
        itemName={props.sidenavItemNames[i]}
        itemLink={props.sidenavItemLinks[i]}
      />
    );
  }

Afterwards, in my return in SidenavDropdown, I return the {rows} in a div:

  <div className={`overflow-hidden bg-[#283046] rounded-lg transition-transform ease-in duration-300`}>
     {rows}
  </div>

This is also my DropdownItem component:

const DropdownItem = (props) => {
  const [goTo, setGoTo] = useState(false);

  if (goTo) {
    return <Navigate exact to={props.itemLink} />;
  }

  return (
    <div className="...">
      
      <button
        onClick={() => setGoTo(true)}
        className="..."
      >
        {props.itemName}
      </button>
    </div>
  );
};

I am assuming that there is an infinite loop somewhere in my code, re-rendering the component. What I do not understand is why the button itself when clicked, displays this error in the console, as well as removes itself completely from the DOM, inside the dropdown, leaving nothing inside.

Could anyone assist me on this matter?

isherwood
  • 58,414
  • 16
  • 114
  • 157
Antonisu
  • 3
  • 3
  • the issue seems to be related to the way you are handling navigation inside the DropdownItem component. Using useState and conditional rendering with the component is causing unnecessary rerenders and possibly leading to an infinite loop. A better way to handle navigation in React is to use the useHistory hook from the react-router-dom library – Stefan Mar 16 '23 at 13:11

2 Answers2

1

Another option is not to use onClick handlers, but directly use react-router Link component and wrap button inside it. Like in Wrapping a react-router Link in an html button

Vlad Vladov
  • 243
  • 1
  • 5
  • This is probably the best solution, because the `` component also has an actual `href` attribute. Meaning that users can `Ctrl + Left Click` or `Middle Click` to open the navigation item in a new tab. The answer is a bit on the small side. Including an example given the code in the question would probably help a lot. – 3limin4t0r Mar 16 '23 at 14:06
0

I think you should rewrite your dropdownItem commponent slightly since useState doesn't do anything here it could be the cause of the error.

const DropdownItem = (props) => {
  const navigateTo () {
    // call the api of the navigation you use directly
    // return <Navigate exact to={props.itemLink} />;
  }

  return (
    <div className="...">
      
      <button
        onClick={() => navigateTo()}
        className="..."
      >
        {props.itemName}
      </button>
    </div>
  );
};
P-A
  • 1,161
  • 12
  • 16