React中使用Ant Design语法无内容渲染问题:为List的renderItem添加Collapse组件后数据不显示的排查与修复
问题描述
我是React新手,尝试编写了如下Students组件:
const Students = (props) => { let id = props.students; const [studentsData, setStudentsData] = useState(null); const url = "http://localhost:2021/students-data/" + id; console.log(url); useEffect(() => { axios.get(url).then((res) => { setStudentsData(res.data); }); }, [url]); if (!studentsData) { return <Spin />; } // console.log(studentsData) return ( <List dataSource={studentsData} renderItem={(item) => { <List.Item key={item._id}> <Collapse style={{ minWidth: "257px" }}> <Panel header={item.name}> <Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}> <Col className="gutter-row index" span={8}> <div>Year Of Batch</div> </Col> <Col className="gutter-row value" span={16}> <div>{item.yearOfBatch}</div> </Col> </Row> <Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}> <Col className="gutter-row index" span={8}> <div>Skills</div> </Col> <Col className="gutter-row value" span={16}> <div> {item.skills.map((e) => { return e + " , "; })} </div> </Col> </Row> </Panel> </Collapse> </List.Item>; }} /> ); }; export default Students;
我通过axios请求接口获取学生数据,将数据传入Ant Design的List组件,并在renderItem属性中嵌套Collapse组件来展示学生详情,但编译时无任何错误,却始终没有数据渲染。请问将Collapse组件赋值给renderItem属性后数据不渲染的核心问题是什么?该如何修改现有代码使其正常工作?
解决方案
我帮你排查了代码,核心问题其实是**renderItem的箭头函数没有返回JSX元素**,这是React新手很容易踩的坑!
为什么会出现这个问题?
你的renderItem用了带大括号的箭头函数形式:
renderItem={(item) => { <List.Item>...</List.Item>; }}
箭头函数如果用{}包裹代码块,必须显式使用return返回值,否则默认会返回undefined。List组件拿到undefined自然不会渲染任何内容,这就是你看不到数据的原因。
另外还有个小细节:你在处理skills的时候用map返回e + " , ",最后会多一个多余的逗号,用Array.join(', ')会更优雅。
修改后的代码
这里提供两种修复方式,你可以选一种:
方式1:显式添加return
import { useState, useEffect } from 'react'; import axios from 'axios'; import { List, Collapse, Row, Col, Spin } from 'antd'; const { Panel } = Collapse; const Students = (props) => { const id = props.students; const [studentsData, setStudentsData] = useState(null); // 用模板字符串优化URL拼接 const url = `http://localhost:2021/students-data/${id}`; useEffect(() => { axios.get(url) .then((res) => { setStudentsData(res.data); }) // 加上错误处理,避免请求失败后一直loading .catch(err => { console.error('请求学生数据失败:', err); setStudentsData([]); // 空数组避免一直显示Spin }); }, [url]); if (!studentsData) { return <Spin />; } return ( <List dataSource={studentsData} renderItem={(item) => { // 显式返回JSX元素 return ( <List.Item key={item._id}> <Collapse style={{ minWidth: "257px" }}> <Panel header={item.name}> <Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}> <Col className="gutter-row index" span={8}> <div>Year Of Batch</div> </Col> <Col className="gutter-row value" span={16}> <div>{item.yearOfBatch}</div> </Col> </Row> <Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}> <Col className="gutter-row index" span={8}> <div>Skills</div> </Col> <Col className="gutter-row value" span={16}> <div>{item.skills.join(', ')}</div> {/* 用join优化逗号处理 */} </Col> </Row> </Panel> </Collapse> </List.Item> ); }} /> ); }; export default Students;
方式2:使用箭头函数隐式返回(去掉大括号)
import { useState, useEffect } from 'react'; import axios from 'axios'; import { List, Collapse, Row, Col, Spin } from 'antd'; const { Panel } = Collapse; const Students = (props) => { const id = props.students; const [studentsData, setStudentsData] = useState(null); const url = `http://localhost:2021/students-data/${id}`; useEffect(() => { axios.get(url) .then((res) => { setStudentsData(res.data); }) .catch(err => { console.error('请求学生数据失败:', err); setStudentsData([]); }); }, [url]); if (!studentsData) { return <Spin />; } return ( <List dataSource={studentsData} renderItem={(item) => ( // 用小括号代替大括号,实现隐式返回 <List.Item key={item._id}> <Collapse style={{ minWidth: "257px" }}> <Panel header={item.name}> <Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}> <Col className="gutter-row index" span={8}> <div>Year Of Batch</div> </Col> <Col className="gutter-row value" span={16}> <div>{item.yearOfBatch}</div> </Col> </Row> <Row gutter={[16, { xs: 8, sm: 16, md: 24, lg: 32 }]}> <Col className="gutter-row index" span={8}> <div>Skills</div> </Col> <Col className="gutter-row value" span={16}> <div>{item.skills.join(', ')}</div> </Col> </Row> </Panel> </Collapse> </List.Item> )} /> ); }; export default Students;
额外优化建议
- 给axios请求加上错误处理,避免接口失败后组件一直处于loading状态;
- 初始化
studentsData可以用空数组[]代替null,这样if (!studentsData)的判断更符合数组的逻辑; - URL拼接用模板字符串更易读;
- skills的展示用
join(', ')比map拼接更简洁,还能避免多余的尾逗号。
内容的提问来源于stack exchange,提问作者Naga Sai
相关产品推荐
相关产品推荐

