Next.js跨文件加载动态数据到主页时接口数据未正常渲染问题
问题根因
getInitialProps是Next.js的专属数据拉取API,仅pages目录下的页面级组件会被框架自动调用该方法。你将该方法写在/src/components/下的公共子组件中,直接导入使用时该方法根本不会执行,自然拿不到返回的stars字段传入组件props。- 页面中渲染组件时写的是
<subNav />,JSX语法规则要求自定义组件必须首字母大写,且标签名需要和导入的组件名完全匹配,小写开头的标签会被React识别为原生HTML标签,无法正确绑定你导入的组件逻辑。
修复方案
推荐使用「页面拉取数据、子组件负责展示」的标准Next.js写法,兼顾服务端渲染能力:
- 改造Subnav为纯展示组件,移除内部的
getInitialProps逻辑,仅负责接收props渲染:
// /src/components/Subnav.js import React, { Component } from "react"; class Subnav extends Component { render() { return <div>Next stars: {this.props.stars}</div>; } } export default Subnav;
- 将数据拉取逻辑移到pages目录下的页面组件中,拿到数据后通过props传递给Subnav,同时修正组件渲染的标签名大小写:
// 注意:该文件必须放在pages目录下,getInitialProps才会生效 import React from "react"; import Subnav from "../src/components/Subnav"; function Page({ stars }) { return ( <Subnav stars={stars} /> ) } Page.getInitialProps = async () => { const res = await fetch("https://api.github.com/repos/vercel/next.js"); const json = await res.json(); return { stars: json.stargazers_count }; } export default Page;
如果不需要服务端渲染获取数据,也可以直接在Subnav组件的挂载生命周期里自行发起请求,不需要依赖页面传值:
// /src/components/Subnav.js import React, { Component } from "react"; class Subnav extends Component { state = { stars: null } async componentDidMount() { const res = await fetch("https://api.github.com/repos/vercel/next.js"); const json = await res.json(); this.setState({ stars: json.stargazers_count }) } render() { return <div>Next stars: {this.state.stars ?? '加载中'}</div>; } } export default Subnav;
对应的页面只需要正确渲染大写标签即可:
import React from "react"; import Subnav from "../src/components/Subnav"; function Page() { return <Subnav /> } export default Page
注意:所有自定义React组件在JSX中渲染时,必须保持首字母大写,且标签名和导入的组件变量名完全一致,否则会出现渲染异常。
内容的提问来源于stack exchange,提问作者orbnexus
相关产品推荐
相关产品推荐

