Reputation: 21
I am trying to use router function to send user to login page but I get an error stating:
Unhandled Runtime Error Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
NextJs code:
"use client";
import React, { useEffect, useState } from "react";
import styles from "./page.module.css";
import useSWR from "swr";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import Image from "next/image";
const Dashboard = () => {
const session = useSession();
const router = useRouter();
//NEW WAY TO FETCH DATA
const fetcher = (...args) => fetch(...args).then((res) => res.json());
const { data, mutate, error, isLoading } = useSWR(
`/api/posts?username=${session?.data?.user.name}`,
fetcher
);
if (session.status === "loading") {
return <p>Loading...</p>;
}
if (session.status === "unauthenticated") {
router?.push("/dashboard/login");
}
const handleSubmit = async (e) => {
e.preventDefault();
const title = e.target[0].value;
const desc = e.target[1].value;
const img = e.target[2].value;
const content = e.target[3].value;
try {
await fetch("/api/posts", {
method: "POST",
body: JSON.stringify({
title,
desc,
img,
content,
username: session.data.user.name,
}),
});
mutate();
e.target.reset()
} catch (err) {
console.log(err);
}
};
const handleDelete = async (id) => {
try {
await fetch(`/api/posts/${id}`, {
method: "DELETE",
});
mutate();
} catch (err) {
console.log(err);
}
};
if (session.status === "authenticated") {
return (
<div className={styles.container}>
<div className={styles.posts}>
{isLoading
? "loading"
: data?.map((post) => (
<div className={styles.post} key={post._id}>
<div className={styles.imgContainer}>
<Image src={post.img} alt="" width={200} height={100} />
</div>
<h2 className={styles.postTitle}>{post.title}</h2>
<span
className={styles.delete}
onClick={() => handleDelete(post._id)}
>
X
</span>
</div>
))}
</div>
<form className={styles.new} onSubmit={handleSubmit}>
<h1>Add New Post</h1>
<input type="text" placeholder="Title" className={styles.input} />
<input type="text" placeholder="Desc" className={styles.input} />
<input type="text" placeholder="Image" className={styles.input} />
<textarea
placeholder="Content"
className={styles.textArea}
cols="30"
rows="10"
></textarea>
<button className={styles.button}>Send</button>
</form>
</div>
);
}
};
export default Dashboard;
I am getting error at this line:
router?.push("/dashboard/login");
I am also getting this warning in the console:
Warning: Cannot update a component (Router
) while rendering a different component (Dashboard
). To locate the bad setState() call inside Dashboard
.
Upvotes: 2
Views: 1775
Reputation: 2863
You are receiving this error because you calling a function directly in your component definition rather than wrapping it in a callback or an effect. You path validation should reside in a useEffect
.
// here you validate the session status upon mount
useEffect(() => {
if (session.status === "unauthenticated") {
router?.push("/dashboard/login");
}
}, [session.status]);
// this is ok since you're just conditionally rendering something
if (session.status === "loading") {
return <p>Loading...</p>;
}
If you can access the session object on the server side it may be a feasible approach to contain this logic in a dedicates server component.
Upvotes: 1