如何在Next.js中实现跨页面可复用的HTML组件(左侧目录栏场景)
解决Next.js中可复用目录组件的问题
嘿,我来帮你搞定这个组件复用的问题!你遇到的核心问题之一是React组件的命名规范——React要求自定义组件必须以大写字母开头,小写开头的标签会被React当作原生HTML标签处理,所以你之前的table_of_contents组件才没法正常渲染。接下来一步步教你正确实现:
1. 创建符合规范的目录组件
首先在项目里新建一个components目录(这是Next.js存放可复用组件的常规位置),然后创建components/TableOfContents.js文件,把左侧目录的代码移进去,注意组件名改为大写开头:
import React from 'react'; import styles from '../styles/Home.module.css'; // 确保样式文件路径正确 export default function TableOfContents() { return ( <div className={styles.left_pane}> <h3>1. Overview</h3> <div className={styles.subsection_nav_link}> <p>1.1 Hey</p> <p>1.2 Hey</p> </div> <h3>2. Hey</h3> <div className={styles.subsection_nav_link}> <h4>2.1 Hey</h4> <div className={styles.subsection_nav_link}> <p>2.1.1 Hey</p> <p>2.1.2 Hey</p> <p>2.1.3 Hey </p> </div> <h4>2.2 Hey</h4> <h4>2.3 Hey</h4> <div className={styles.subsection_nav_link}> <p>2.3.1 Hey</p> <p>2.3.2 Hey</p> </div> <h4>2.4 Hey</h4> </div> <h3>3. Hey</h3> <div className={styles.subsection_nav_link}> <p>3.1 Hey</p> <p>3.2 Hey</p> <p>3.3 Hey</p> <p>3.4 Hey</p> </div> <h3>4. Hey</h3> <h4>4.1 Hey</h4> <h4>4.2 Hey</h4> <h4>4.3 Hey</h4> <div className={styles.subsection_nav_link}> <p>4.3.1 Hey</p> <p>4.3.2 Hey (BT)</p> <p>4.3.3 Hey</p> <p>4.3.4 Hey</p> <p>4.3.5 Hey</p> <p>4.3.6 Hey</p> </div> </div> ); }
2. 在Home组件中引入并使用该组件
回到你的pages/index.js(Home组件),导入刚刚创建的TableOfContents组件,替换原来硬编码的左侧目录代码:
import React from 'react'; import styles from '../styles/Home.module.css'; import TableOfContents from '../components/TableOfContents'; // 导入复用组件 export default function Home() { return ( <div className={styles.grid_container}> {/* 用复用组件替代原硬编码内容 */} <TableOfContents /> <div className={styles.center_pane}> <h2>Center Pane</h2> <p>HeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHeyHey</p> </div> <div className={styles.right_pane}> <h2>Right Pane</h2> </div> <div className={styles.footer}> Test </div> </div> ); }
3. 进阶优化:动态生成目录(可选)
你之前导入了table_of_contents数据文件,说明你可能想避免硬编码目录内容。可以把数据传入组件,让组件更灵活。假设你的test.js数据结构如下:
// test.js export default [ { title: '1. Overview', subsections: ['1.1 Hey', '1.2 Hey'] }, { title: '2. Hey', subsections: [ { title: '2.1 Hey', subsubsections: ['2.1.1 Hey', '2.1.2 Hey', '2.1.3 Hey'] }, '2.2 Hey', { title: '2.3 Hey', subsubsections: ['2.3.1 Hey', '2.3.2 Hey'] }, '2.4 Hey' ] }, // 其他章节数据... ];
修改TableOfContents组件来动态渲染数据:
import React from 'react'; import styles from '../styles/Home.module.css'; import tableData from '../test'; // 导入目录数据 export default function TableOfContents() { return ( <div className={styles.left_pane}> {tableData.map((section, idx) => ( <div key={idx}> <h3>{section.title}</h3> {section.subsections && ( <div className={styles.subsection_nav_link}> {section.subsections.map((item, subIdx) => { if (typeof item === 'string') { // 普通子章节 return <p key={subIdx}>{item}</p>; } // 包含子子章节的层级 return ( <div key={subIdx}> <h4>{item.title}</h4> {item.subsubsections && ( <div className={styles.subsection_nav_link}> {item.subsubsections.map((subItem, subsubIdx) => ( <p key={subsubIdx}>{subItem}</p> ))} </div> )} </div> ); })} </div> )} </div> ))} </div> ); }
这样以后修改目录内容,只需要更新test.js的数据即可,不用改动组件代码,复用性更强。
常见问题排查
- 路径正确性:确保组件和样式文件的导入路径与你的项目目录结构匹配,否则会出现找不到文件或样式不生效的问题。
- 组件命名:再次强调,自定义组件必须大写开头,大驼峰(如
TableOfContents)是React组件的标准命名方式。
这样处理后,你的目录组件就能正常渲染,并且可以在其他页面直接复用啦!
内容的提问来源于stack exchange,提问作者Cogito Ergo Sum
相关产品推荐
相关产品推荐

