React Bootstrap基于一维数组动态创建表格行及报错修复
问题场景
需要根据存储列名的数组动态渲染两列表格:
- 第一列(Column)展示对应列名
- 第二列(Import As)渲染类型选择按钮(下拉逻辑后续实现,当前仅渲染按钮即可)
初始代码运行抛出报错:Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag
列名数据通过d3读取csv文件加载,数据格式示例:["name", "address", "zip", "number", ...]
错误原因
两个核心问题导致报错:
- 状态初始值设置错误:
useState初始值传了null,组件首次渲染时cols为null,直接调用.map()方法会触发类型错误,要等csv异步加载完成后cols才会变成数组。 - JSX结构不符合规则:
map循环的返回值里直接放了两个并列的<td>元素,既违反了JSX单根节点的语法要求,也不符合HTML表格的结构规范——<tbody>的直接子元素必须是<tr>行标签,不能直接放<td>单元格。
原始错误代码
状态与数据加载部分:
const [cols, setCols] = useState(null); d3.csv('/test.csv').then(data -> setCols(data.columns)); console.log(cols); // ["name", "address", "zip", "number", ...]
表格渲染部分:
<ReactBootstrap.Table striped bordered hover> <thead> <tr> <th>Column</th> <th>Import As</th> </tr> </thead> <tbody> { cols.map((col) => ( <td><p>{col}</p></td> <td><div><button>Skipped</button></div></td> )) } </tbody> </ReactBootstrap.Table>
修复方案
对应两个问题做修改即可:
- 把
useState初始值从null改为空数组[],首次渲染时调用map不会报错,等csv加载完成后状态自动更新触发重渲染。 - 循环返回的内容外层补上
<tr>行标签,把两个<td>包裹在行标签内,既满足JSX单根节点要求,也符合表格DOM结构。如果不想额外生成DOM节点,也可以用Fragment包裹<tr>,不过当前场景下<tr>本身就是单个根节点,其实不需要额外套Fragment。
额外注意:React列表渲染要求循环生成的元素必须添加唯一的
key属性,直接用列名作为key值即可,能避免列表渲染的性能问题和控制台警告。
修复后的完整代码:
const [cols, setCols] = useState([]); // 数据加载逻辑 d3.csv('/test.csv').then(data => setCols(data.columns)); // 表格渲染 <ReactBootstrap.Table striped bordered hover> <thead> <tr> <th>Column</th> <th>Import As</th> </tr> </thead> <tbody> { cols.map((col) => ( // 此处Fragment可以省略,直接返回<tr>即可 <Fragment> <tr key={col}> <td><p>{col}</p></td> <td><div><button>Skipped</button></div></td> </tr> </Fragment> )) } </tbody> </ReactBootstrap.Table>
更精简的循环写法(去掉不必要的Fragment):
cols.map((col) => ( <tr key={col}> <td><p>{col}</p></td> <td><div><button>Skipped</button></div></td> </tr> ))
内容的提问来源于stack exchange,提问作者Supez38
相关产品推荐
相关产品推荐

