React+NextJS中为表格列添加路由跳转按钮的实现方法
解决React/Next.js表格中添加跳转按钮的问题
我正在学习React和Next.js,制作一个仪表盘项目。需要在departments.js页面的表格中,为「Actions」列添加「View Department」按钮,点击按钮可跳转到对应部门的页面(例如点击Marketing行的按钮跳转至/mark)。表格数据来自硬编码的JSON,但现有Table组件无法实现按钮渲染,尝试的方案失败,寻求可行的实现方法。
现有代码
数据定义
const data = [ { name: "Customer Service", num: '56', dept:'custserv' }, { name: "Human Resources", num: '21', dept:'hr' }, { name: "Quality Assurance", num: '13', dept:'qa' }, { name: "Marketing", num: '30', dept:'mark' }, { name: "Research and Development", num: '17', dept:'rnd' }, { name: "Operations", num: '49', dept:'ops' }, { name: "Sales", num: '37', dept:'sales' }, { name: "Distribution", num: '26', dept:'dist' }, { name: "IT", num: '12', dept:'it' }, ] const column = [ { heading: 'Department', value: 'name' }, { heading: 'No. of Employees', value: 'num' }, { heading: 'Actions', value: 'dept' }, ];
Table组件代码
const Table = ({ data, column }) => { return ( <table> <thead> <tr> {column.map((item, index) => <TableHeadItem item={item} key={index} />)} </tr> </thead> <tbody> {data.map((item, index) => <TableRow item={item} column={column} key={index} />)} </tbody> </table> ) } const TableHeadItem = ({ item }) => <th>{item.heading}</th> const TableRow = ({ item, column }) => ( <tr> {column.map((columnItem, index) => { if(columnItem.value.includes('.')) { const itemSplit = columnItem.value.split('.') return <td key={index}>{item[itemSplit[0]][itemSplit[1]]}</td> } return <td key={index}>{item[`${columnItem.value}`]}</td> })} </tr> ) export default Table
失败的尝试
const viewDeptBtn = (dept) => { return ( <button className={styles.viewDeptBtn} onClick={() => router.push('/'+dept)}> View Department </button> ) } const column = [ { heading: 'Department', value: 'name' }, { heading: 'No. of Employees', value: 'num' }, { heading: 'Actions', value: viewDeptBtn('dept') }, ];
可行实现方案
现有Table组件仅支持渲染数据字段的文本值,没有预留自定义渲染逻辑。我们可以通过修改列配置和TableRow组件来实现需求:
修改列配置,添加自定义render函数
给Actions列定义render函数,接收当前行数据作为参数,动态生成跳转按钮:import { useRouter } from 'next/router'; import styles from './Departments.module.css'; // 假设样式文件路径 const DepartmentsPage = () => { const router = useRouter(); const data = [/* 保持原数据不变 */]; const column = [ { heading: 'Department', value: 'name' }, { heading: 'No. of Employees', value: 'num' }, { heading: 'Actions', render: (item) => ( <button className={styles.viewDeptBtn} onClick={() => router.push(`/${item.dept}`)}> View Department </button> ) }, ]; return <Table data={data} column={column} />; }; export default DepartmentsPage;更新TableRow组件,支持自定义渲染
修改TableRow组件,优先判断列是否存在render函数,存在则调用函数生成内容,否则按原逻辑渲染文本:const TableRow = ({ item, column }) => ( <tr> {column.map((columnItem, index) => { // 优先处理自定义render逻辑 if (columnItem.render) { return <td key={index}>{columnItem.render(item)}</td>; } // 原有嵌套字段处理 if(columnItem.value.includes('.')) { const itemSplit = columnItem.value.split('.') return <td key={index}>{item[itemSplit[0]][itemSplit[1]]}</td> } // 普通字段渲染 return <td key={index}>{item[columnItem.value]}</td> })} </tr> )
失败原因说明
之前的尝试在列配置初始化时就执行了viewDeptBtn('dept'),得到的是一个静态按钮,无法关联到每一行的实际dept值。通过在render函数中接收当前行数据,才能动态获取每行的部门标识,实现正确的跳转逻辑。
内容的提问来源于stack exchange,提问作者Safwan Parkar
相关产品推荐
相关产品推荐

