NextJS 应用程序路由器:具有数据获取功能的客户端组件,在悬念边界内进行静态渲染

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

我有这个问题的复制品这里

我正在玩 NextJS 应用程序路由器和 Suspense。

我有两个使用 React Query 获取数据的简单客户端组件的实现。一个使用

useSuspenseQuery
,另一个使用常规查询。

export function TodosRq() {

    const query = useQuery<Array<{id: number, title: string}>>({ queryKey: ['todos'], queryFn: async () => {

        await new Promise((res) => setTimeout(res, 10000));
        const res = await  fetch("https://jsonplaceholder.typicode.com/todos")
        return res.json();
    } })


    return <div>
        {query.data?.map((v) => {
            return <div> 
                RQ
                {v.id} {v.title}
            </div>
        })}
    </div>

}
export function TodosRqSuspense() {

    const query = useSuspenseQuery<Array<{id: number, title: string}>>({ queryKey: ['todos'], queryFn: async () => {

        await new Promise((res) => setTimeout(res, 10000));
        const res = await  fetch("https://jsonplaceholder.typicode.com/todos")
        return res.json();
    } })


    return <div>
        {query.data.map((v) => {
            return <div> 
                RQ
                {v.id} {v.title}
            </div>
        })}
    </div>

}

在我的应用程序路由器页面中,我可以渲染以下任一组件:

      {/* nb. this suspense boundary won't do anything */}
      <Suspense fallback={'rq loading'}>
        <h2>Todos RQ</h2>
        <TodosRq/>
      </Suspense>

      <Suspense fallback={'rq loading'}>
        <h2>Todos RQ</h2>
        <TodosRqSuspense/>
      </Suspense>

直观地说,我在这里期望的是服务器渲染将在加载状态下渲染应用程序,将其流式传输到客户端,然后客户端接管并进行 API 调用。

但是,我实际观察到,在使用悬念查询的情况下,实际上 NextJS 将 静态渲染 应用于

TodosRqSuspense
组件。也就是说,在生产版本中,它返回预渲染的 HTML,从不等待 10 秒。

观察开发服务器的行为以及生产构建非常重要。

开发服务器 生产构建
TodosRq 我们看不到悬念的边界。我们等待 10 秒直到内容出现。内容不会出现在根文档中。 我们看不到悬念的边界。我们等待 10 秒直到内容出现。内容不会出现在根文档中。
TodosRq悬念 我们看到了悬念的边界。我们等待 10 秒直到内容出现。内容出现在根文档中。 (开发服务器似乎做了一些有趣的事情,它可以修改网络请求的响应正文) 我们立即获取内容。内容在根文档中。

我在这里缺少什么?

以下是文档的相关部分以及我的理解:

静态与动态渲染 - 对于服务器组件,默认行为是所有内容都将静态渲染(即在构建时渲染),即使涉及数据获取除非它适合其中之一例外,例如使用

cookies
connection
方法。

客户端组件 - 客户端组件在服务器上预渲染(首先在服务器上渲染),然后当它们到达客户端时,工作就会在客户端上完成。

Suspense - 允许“第一次渲染”显示所有加载骨架等,然后如果使用 RSC,那么它们会流入,而且,这就是我有一些误解的地方,我本以为客户端组件会仍然在客户端获取数据,然后在完成时显示。

NextJS 建议什么 - NextJS 建议您在服务器组件中获取数据,只是为了清楚起见。然而,在某种迁移的背景下,我们可能将某些东西保留为客户端组件是有意义的。无论如何,我试图理解这里的细微差别。

nb。如果我们将

useSearchParams
添加到我们的客户端组件,那么这种行为就不会发生,并且其行为符合我的直觉。

reactjs next.js react-query react-suspense
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.