具有 Suspense 回退功能的 Nextjs 客户端组件无法工作

问题描述 投票:0回答:1

我正在服务器组件中加载客户端组件,但尝试显示后备加载程序,直到通过 API 在客户端中获取数据。

我有以下服务器组件,其中包含客户端组件

import { LoggedInUserModel } from "@/models/common/logged-in-user-model";
import { Suspense } from "react";
import dynamic from "next/dynamic";
import ProfileLoading from "./loading22";
const UserProfile = dynamic(() => import("./components/userProfile"), {
  ssr: false,
});

const MyProfile = async () => {
 const user: LoggedInUserModel = await userService.getUser();
  return (
    <>
      <div className="row mt-3 justify-content-md-center">
        <div className="col-12 col-md-8">
          <nav
            aria-label="breadcrumb"
            className="p-3 bg-white rounded-3 shadow-sm mb-4"
          >
            <ol className="breadcrumb mb-0">
              <li className="breadcrumb-item">
                <a className="text-decoration-none">
                  <i className="fa-solid fa-user"></i> My Profile
                </a>
              </li>
            </ol>
          </nav>
        </div>

        <UserProfile user={user} />

      </div>
    </>
  );
};

export default MyProfile;

我的客户端组件用户配置文件是

"use client";
import { UserProfileModel } from "./../../../../models/User/user-profile-model";
import { Suspense, lazy, use, useEffect, useState } from "react";
import fetchClientData from "@/lib/fetchClientData";
import { LoggedInUserModel } from "@/models/common/logged-in-user-model";
import ProfileLoading from "../loading22";
import React from "react";
const AbcProfile = lazy(() => import("./abcprofile"));

type UserProfileProps = {
  user: LoggedInUserModel;
};
const UserProfile = ({ user }: UserProfileProps) => {
 

  return (
    <Suspense fallback={<h2>Data loading...........</h2>}>
      <AbcProfile />
    </Suspense>
  );
};

export default UserProfile;

AbcProfile 组件:

import { use, useEffect, useState } from "react";

const AbcProfile = () => {
  use(
    fetch(`/api/user/profile/6490986e0d0ce1756d2b491b`).then((res) =>
      res.json()
    )
  );

  return <h2>Data loaded</h2>;
};

export default AbcProfile;

当我运行代码时,它确实显示了后备加载程序,但 API 被调用 4 次以从服务器获取数据。为什么?如何正确 在客户端组件中使用 nextjs 的 Suspense 吗?

reactjs next.js react-hooks next.js13 react-suspense
1个回答
0
投票

页面SSR和组件CSR的混合模式似乎有一些局限性。例如,Suspense 组件不会回退,因为它认为它已经渲染了客户端组件。但客户端组件可能正在调用 API 来加载数据。对于这种混合方法,我将使用 useEffect 挂钩来调用 API,然后显式加载回退。当页面和组件使用完整的 SSR 或 CSR 时,Suspense 会按预期工作。

const UserProfile = ({ user }: UserProfileProps) => {
 
    const [profile, setProfile] = useState(null); 

    useEffect(() => {
      const fetchData = async () => {              
        const data = fetch(`/api/user/profile/6490986e0d0ce1756d2b491b`).then((res) =>
          res.json()
        )
        setProfile(data);      
      };  
      fetchData();
    }, []); // Re-fetch query changes)

    if (!profile){
      return (<h2>Data loading...........</h2>)
    }

    return (    
      <h1>{profile.name}</h1>            
    );
  };
© www.soinside.com 2019 - 2024. All rights reserved.