如何在Next.js项目中获取JSON文件的mainMenu数据并渲染到页面
问题排查与修正方案
1. 自定义App的getInitialProps返回值不规范
Next.js 自定义App的getInitialProps必须先执行默认的App.getInitialProps(ctx)获取页面基础属性,否则所有子页面的pageProps会丢失,子页面通过getStaticProps/getServerSideProps获取的数据都会失效。
你当前直接返回{ props: res.data }的写法,会覆盖默认返回的属性,导致pageProps为空。2. 菜单遍历逻辑完全错误
你调用Object.entries(props)会把props对象转换为[键名, 键值]格式的二维数组,比如你的接口返回{ mainMenu: [{url: 'home', label: '首页'}, ...] },转换后得到的是[ ['mainMenu', [菜单数组]] ]。
此时你双层map的逻辑是:先遍历外层数组拿到['mainMenu', [菜单数组]],再遍历这个数组的两个元素,第一个元素是字符串mainMenu,遍历字符串会得到单个字符,自然渲染不出正确的菜单项,甚至会抛出类型错误。3. 缺少列表唯一key属性
你渲染li列表项时没有添加唯一key属性,会触发React的渲染警告,也会影响组件diff更新的性能。4. 不必要的接口请求(如果是本地JSON文件)
如果你是读取项目内的静态JSON文件,不需要用axios发请求,直接import mainMenu from './xxx/mainMenu.json'导入即可,不需要走服务端获取逻辑,性能更高。
修正后的代码示例
import App from 'next/app' import axios from 'axios' // 如果是本地JSON,直接导入即可,不需要下方的getInitialProps请求逻辑 // import mainMenu from './mainMenu.json' function MyApp({ Component, pageProps, mainMenu }) { return ( <> <Header /> <div className="container"> <nav className={styles.navbar}> <div className={styles.navbarInner}> <ul className={styles.navbarList}> {/* 直接单层遍历菜单数组即可 */} {mainMenu.map((elem, index) => ( <li key={index} className={styles.navbarListItem}> {/* Next.js 13+ 不需要嵌套a标签,直接把内容写在Link组件内即可 */} <Link href={`/${elem.url}`}> <a className={styles.navbarListLink}>{elem.label}</a> </Link> </li> ))} </ul> <Input /> </div> </nav> </div> <Component {...pageProps} /> </> ) } MyApp.getInitialProps = async (ctx) => { // 先获取默认的App初始属性 const appProps = await App.getInitialProps(ctx) const res = await axios.get(`${url}/global`) // 把菜单数据和原有属性合并返回 return { ...appProps, mainMenu: res.data.mainMenu } } export default MyApp
内容的提问来源于stack exchange,提问作者Cracker
相关产品推荐
相关产品推荐

