Next.js中fetch获取数据显示undefined,组件引入layout时异常
这个问题我太熟悉了,核心原因是Next.js的getInitialProps仅在页面级组件(比如index.js、about.js这类直接对应路由的组件)中会被框架自动调用,你在header.js或footer.js这类非页面组件里定义它,根本不会触发执行,所以自然拿不到数据,返回undefined。
另外还要提一句:你原代码里还有个小问题——fetch和response.json()都是异步操作,但没加await,就算在页面组件里用,拿到的也会是Promise对象而非实际数据,这个得先修正。
下面给你两种靠谱的解决方案:
方案一:页面组件获取数据,通过Props传递给子组件
这是Next.js推荐的做法,把数据获取逻辑放在页面组件的getInitialProps里,再逐层传递给Layout、Header/Footer:
- 在页面组件(比如
index.js)里修正并完善数据获取:
static async getInitialProps() { // 必须加await等待异步操作完成 const response = await fetch('http://localhost/coc/api/singletons/get/topbar/',{ headers: { 'Cockpit-Token': 'ae6d9be66c544f76bf4e0676357253' } }) const data = await response.json(); return { data } } render() { // 将数据传递给Layout组件 return <Layout topbarData={this.props.data}> {/* 页面内容 */} </Layout> }
- 在
layout.js中接收数据,再传递给Header:
const Layout = ({ topbarData, children }) => { return ( <> <Header data={topbarData} /> {children} <Footer /> </> ) }
- 在
header.js中直接使用props里的数据:
const Header = ({ data }) => { // 这里就可以正常使用data了 return <header>{/* 你的Header内容 */}</header> }
方案二:在Header/Footer中使用客户端异步获取(useEffect)
如果不想依赖页面组件传递数据,也可以在组件内部用React的useEffect钩子在客户端渲染时获取数据,适合不需要服务端渲染数据的场景:
import { useEffect, useState } from 'react' const Header = () => { const [data, setData] = useState(null) const [isLoading, setIsLoading] = useState(true) useEffect(() => { const fetchTopbarData = async () => { try { const response = await fetch('http://localhost/coc/api/singletons/get/topbar/',{ headers: { 'Cockpit-Token': 'ae6d9be66c544f76bf4e0676357253' } }) const result = await response.json() setData(result) } catch (err) { console.error('获取数据失败:', err) } finally { setIsLoading(false) } } fetchTopbarData() }, []) // 处理加载状态 if (isLoading) return <div>Loading header...</div> if (!data) return <div>无法加载header数据</div> return <header>{/* 使用data渲染内容 */}</header> }
注意:这种方式下,页面首次渲染时Header会先显示loading状态,等客户端请求完成后才会显示实际内容,不适合需要SEO的场景。
内容的提问来源于stack exchange,提问作者Chandan Manna
相关产品推荐
相关产品推荐

