NextJS:超过最大更新深度错误

aamkag61  于 2023-06-29  发布在  其他
关注(0)|答案(1)|浏览(155)

我试图使用路由器功能将用户发送到登录页面,但我收到一个错误:
未处理的运行时错误:超过最大更新深度。当一个组件在componentWillUpdate或componentDidUpdate中反复调用setState时,就会发生这种情况。React限制嵌套更新的数量以防止无限循环。
NextJs代码:

"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;

在这一行出现错误:router?.push("/dashboard/login");
我在控制台中也收到了这个警告:
警告:无法在呈现不同组件(Dashboard)时更新组件(Router)。查找Dashboard中错误的setState()调用。

jjhzyzn0

jjhzyzn01#

您收到此错误是因为您直接在组件定义中调用函数,而不是将其 Package 在回调或效果中。路径验证应该驻留在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>;
}

如果您可以在服务器端访问会话对象,那么将此逻辑包含在专用服务器组件中可能是一种可行的方法。

相关问题