最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Suspense does not work on nextjs, waiting promise but not displaying loading dialog - Stack Overflow

programmeradmin6浏览0评论
"use client";

import React, { Suspense, useEffect, useState } from "react";
import TopBar from "../components/topBar";
import DataPost from "../components/data";

type User = {
  albumId: number;
  id: number;
  title: string;
  url: string;
  thumbnailUrl: string;
};

function UsersClient() {
  const [users, setUsers] = useState<User[]>([]);
  const [error, setError] = useState("");

  useEffect(() => {
    async function fetchUsers() {
      await new Promise((resolve) => setTimeout(resolve, 5000));

      try {
        const response = await fetch(
          ";
        );
        if (!response.ok) {
          throw new Error("Network response was not ok");
        }
        const data = await response.json();
        setUsers(data);
      } catch (error) {
        setError((error as Error).message);
      }
    }
    fetchUsers();
  }, []);

  if (error) {
    return <div>Error: {error}</div>;
  }
  return (
    <>
      <TopBar />
      <Suspense fallback={<div>Loading...</div>}>
              <div className="grid grid-cols-5">
      {users.map((user) => (
        <div key={user.id}>
          <div className="h-32 w-32 border border-black">
            <h1>{user.title}</h1>
            <img src={user.url} alt={user.title} />
          </div>
        </div>
      ))}
    </div>
      </Suspense>
    </>
  );
}

export default UsersClient;

Error

Suspense does not work on nextjs, waiting promise but not displaying loading div

Expected:

displaying loading div

Can someone provide an explanation for why suspense is not functioning in this situation? Loading promise was working fine for 5 seconds, but it was not displaying the loading div.

I'm trying to figure it out, but I'm not able to.

"use client";

import React, { Suspense, useEffect, useState } from "react";
import TopBar from "../components/topBar";
import DataPost from "../components/data";

type User = {
  albumId: number;
  id: number;
  title: string;
  url: string;
  thumbnailUrl: string;
};

function UsersClient() {
  const [users, setUsers] = useState<User[]>([]);
  const [error, setError] = useState("");

  useEffect(() => {
    async function fetchUsers() {
      await new Promise((resolve) => setTimeout(resolve, 5000));

      try {
        const response = await fetch(
          "https://jsonplaceholder.typicode/albums/1/photos"
        );
        if (!response.ok) {
          throw new Error("Network response was not ok");
        }
        const data = await response.json();
        setUsers(data);
      } catch (error) {
        setError((error as Error).message);
      }
    }
    fetchUsers();
  }, []);

  if (error) {
    return <div>Error: {error}</div>;
  }
  return (
    <>
      <TopBar />
      <Suspense fallback={<div>Loading...</div>}>
              <div className="grid grid-cols-5">
      {users.map((user) => (
        <div key={user.id}>
          <div className="h-32 w-32 border border-black">
            <h1>{user.title}</h1>
            <img src={user.url} alt={user.title} />
          </div>
        </div>
      ))}
    </div>
      </Suspense>
    </>
  );
}

export default UsersClient;

Error

Suspense does not work on nextjs, waiting promise but not displaying loading div

Expected:

displaying loading div

Can someone provide an explanation for why suspense is not functioning in this situation? Loading promise was working fine for 5 seconds, but it was not displaying the loading div.

I'm trying to figure it out, but I'm not able to.

Share Improve this question edited Mar 22 at 10:39 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 22 at 10:26 eko prameko pram 654 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

Couple of things here:

  1. <Suspense> boundary should be wrapping the component which does the fetching here. (Doc) Here you have only one component. In your case extract another component and do the data fetching in it.

  2. <Suspense> cannot figure out data fetching in effects. (Doc) The data fetching logic should be a part of the component render. In case of Next.js, use something like:


   async function fetchUsers() {
      await new Promise((resolve) => setTimeout(resolve, 5000));

      try {
        const response = await fetch(
          "https://jsonplaceholder.typicode/albums/1/photos"
        );
        if (!response.ok) {
          throw new Error("Network response was not ok");
        }
        const data = await response.json();
        return data;
      } catch (error) {
       //Throw error here
        throw error;
      }
    }
 
function UsersClient() {
  const [users, setUsers] = useState<User[]>([]);
 
  const { users } = await fetchUsers();
 
  return (
    <>
              <div className="grid grid-cols-5">
      {users.map((user) => (
        <div key={user.id}>
          <div className="h-32 w-32 border border-black">
            <h1>{user.title}</h1>
            <img src={user.url} alt={user.title} />
          </div>
        </div>
      ))}
    </div>
  );
}

Now basically your wrapper component should have the Suspense boundary. Something like:

const Parent = () => {


return <>
<TopBar />
<Suspense fallback={<div>Loading...</div>}>
<UsersClient />
</Suspense> 
</>


};


与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论