如何在Next.js根客户端页面中从服务端取数并传递给客户端组件
解决方案:Next.js App Router中服务端组件向客户端组件传数据(避免骨架屏)
核心问题梳理
需要在app/page.jsx(服务端组件)中获取数据,传递给依赖React Hooks的客户端组件,同时利用服务端组件特性避免刷新时出现骨架屏/空白,且不能将客户端组件放在根布局中。
纠正错误尝试
- 服务端组件可以正常渲染客户端组件,之前报错是因为客户端组件未声明
'use client',而非服务端组件不能嵌套客户端组件。 'use server'用于定义服务端动作(如表单处理函数),不能用来导出客户端组件,客户端组件必须通过'use client'声明。
正确实现步骤
1. 声明客户端组件
在客户端组件顶部添加'use client'指令,确保可以使用React Hooks,且能被服务端组件正常引入:
// app/components/Bottom.jsx 'use client'; import { useState } from 'react'; export default function Bottom({ initialData }) { // 用服务端传递的初始数据初始化state,后续可按需更新 const [data, setData] = useState(initialData); // 这里可以正常使用任何React Hooks,比如useEffect、useCallback等 return ( <div className="bottom-section"> <p>服务端数据:{data.title}</p> <p>内容:{data.content}</p> </div> ); }
2. 服务端组件获取数据并传递
app/page.jsx默认是服务端组件,直接在这里完成数据获取,将数据作为props传给客户端组件。服务端渲染时会直接把数据注入页面,避免首次加载的空白/骨架屏:
// app/page.jsx import Bottom from './components/Bottom'; // 服务端数据获取函数(可从数据库、外部API拉取) async function fetchPageData() { const res = await fetch('https://your-api-endpoint.com/data', { // 配置数据重新验证规则,仅数据变更时刷新 next: { revalidate: 300, // 5分钟后自动重新验证数据 // 或使用tags实现按需刷新:tags: ['page-data'] } }); if (!res.ok) throw new Error('数据获取失败'); return res.json(); } export default async function HomePage() { // 服务端同步获取数据 const serverData = await fetchPageData(); return ( <main> <h1>首页内容</h1> {/* 将服务端数据传递给客户端组件 */} <Bottom initialData={serverData} /> </main> ); }
3. 数据变更时的按需刷新
如果需要实现仅数据变更时刷新,可以通过以下方式:
- 使用
next.revalidate配置自动刷新间隔,Next.js会在后台静默重新获取数据,更新页面时无空白。 - 若需手动触发刷新,可在服务端函数中使用
tags,结合revalidateTagAPI在数据变更时主动刷新:// 在服务端函数中添加tags async function fetchPageData() { const res = await fetch('https://your-api-endpoint.com/data', { next: { tags: ['page-bottom-data'] } }); return res.json(); } // 在API路由或服务端动作中触发刷新 export async function revalidateBottomData() { 'use server'; revalidateTag('page-bottom-data'); }
方案优势
- 首次加载时服务端已完成数据渲染,无骨架屏/空白区域。
- 客户端组件可正常使用React Hooks,不影响交互逻辑。
- 数据更新时仅刷新变更部分,无需全页重载,保持用户体验。
内容的提问来源于stack exchange,提问作者CrackerKSR
相关产品推荐
相关产品推荐

