I want to render the page according to parameter in URL.
export default function Navbar() {
const [leftHeader, setLeftHeader] = useState("aa");
if (window.location.href.indexOf("/admin/aa") !== -1) {
console.log("aa");
setLeftHeader("aa");
} else if (window.location.href.indexOf("/admin/bb") !== -1) {
console.log("bb");
setLeftHeader("bb");
} else if (window.location.href.indexOf("/admin/cc") !== -1) {
console.log("cc");
setLeftHeader("cc");
} else if (window.location.href.indexOf("/admin/dd") !== -1) {
console.log("dd");
setLeftHeader("dd");
} else if (window.location.href.indexOf("/admin/ee") !== -1) {
console.log("ee");
setLeftHeader("ee");
} else {
console.log("ff"); //when i clicked any element on sidebar, I always get the Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
setLeftHeader("ff");
}
return (
<>
{/* Navbar */}
<nav className="absolute top-0 left-0 w-full z-10 bg-transparent md:flex-row md:flex-nowrap md:justify-start flex items-center p-4">
<div className="w-full mx-autp items-center flex justify-between md:flex-nowrap flex-wrap md:px-12 px-4">
{/* Brand */}
<a
className="text-white text-xl uppercase hidden lg:inline-block font-semibold"
href="#pablo"
onClick={(e) => e.preventDefault()}
>
{leftHeader} {/* This code show the parameters in URL */}
</a>
<ul className="flex-col md:flex-row list-none items-center hidden md:flex">
<UserDropdown />
</ul>
</div>
</nav>
{/* End Navbar */}
</>
);
}
But this code always gives the Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. How can i fix that?
CodePudding user response:
The problem is that when you call setLeftHeader
it triggers a component re-render, causing the chain of if statements to run again, triggering another re-render infinitely. The solution is to use the useEffect
hook to only run the conditional code when the component is mounted:
export default function Navbar() {
const [leftHeader, setLeftHeader] = useState("aa");
useEffect(() => {
if (window.location.href.indexOf("/admin/aa") !== -1) {
console.log("aa");
setLeftHeader("aa");
} else if (window.location.href.indexOf("/admin/bb") !== -1) {
console.log("bb");
setLeftHeader("bb");
} else if (window.location.href.indexOf("/admin/cc") !== -1) {
console.log("cc");
setLeftHeader("cc");
} else if (window.location.href.indexOf("/admin/dd") !== -1) {
console.log("dd");
setLeftHeader("dd");
} else if (window.location.href.indexOf("/admin/ee") !== -1) {
console.log("ee");
setLeftHeader("ee");
} else {
console.log("ff");
setLeftHeader("ff");
}
}, [])
return (
<>
{/* Navbar */}
<nav className="absolute top-0 left-0 w-full z-10 bg-transparent md:flex-row md:flex-nowrap md:justify-start flex items-center p-4">
<div className="w-full mx-autp items-center flex justify-between md:flex-nowrap flex-wrap md:px-12 px-4">
{/* Brand */}
<a
className="text-white text-xl uppercase hidden lg:inline-block font-semibold"
href="#pablo"
onClick={(e) => e.preventDefault()}
>
{leftHeader} {/* This code show the parameters in URL */}
</a>
<ul className="flex-col md:flex-row list-none items-center hidden md:flex">
<UserDropdown />
</ul>
</div>
</nav>
{/* End Navbar */}
</>
);
}
CodePudding user response:
you can fix that by using react router and useEffect where you subscribe to route change and set your state only if the route changed not on every component re-render