React中如何用fetch获取的JSON数据填充Bootstrap网格并解决报错?
问题分析与解决方案
你遇到的错误本质是异步数据加载时机的问题,再加上几个React和Bootstrap的语法小坑,我来一步步帮你解决:
为什么会报错?
组件初始化时this.state.matches是个空数组,而fetch是异步操作——组件会先完成第一次渲染,这时候你直接访问this.state.matches[0].season,相当于在undefined上读取season属性,自然会抛出"Cannot read property 'season' of undefined"的错误。
另外还有两个小问题需要修正:
- React里给元素加类名要用
className,不是原生HTML的class - React的内联样式要写成对象格式,用
style(不是styles),属性名是驼峰式(比如backgroundColor)
修正后的代码示例
下面是优化后的代码,既解决了异步加载的问题,又能自动把所有577条数据渲染到Bootstrap网格中:
class Main extends Component { constructor(){ super(); this.state={ matches: [] }; } componentDidMount(){ fetch('api/matches') .then(res => res.json()) .then(matches => this.setState({matches}, () => console.log('Matches fetched...', matches))); } render() { // 数据未加载完成时显示加载提示 if (this.state.matches.length === 0) { return <div className="container mt-4">加载中...</div>; } // 遍历所有比赛数据,生成Bootstrap网格项 const matchCards = this.state.matches.map((match, index) => ( <div key={match._id || index} className="col-lg-4 mb-4"> <div style={{ backgroundColor: index % 2 === 0 ? 'lavender' : 'lavenderblush', padding: '1rem', borderRadius: '8px' }}> <h5>赛季: {match.season}</h5> <p><strong>对阵双方:</strong> {match.team1} vs {match.team2}</p> <p><strong>获胜方:</strong> {match.winner}</p> <p><strong>最佳球员:</strong> {match.player_of_match}</p> </div> </div> )); return ( <div className="container mt-4"> <div className="row"> {matchCards} </div> </div> ); } }
关键改动说明
- 加载状态处理:在
render开头判断数组长度,为空时显示加载提示,避免访问未定义的属性 - 动态渲染所有数据:用
map遍历matches数组,每条数据生成一个col-lg-4的网格项,这样577条数据会自动按每行3个排列 - React语法修正:把
class改成className,内联样式改成对象格式,同时添加了key属性(React列表渲染必须加,用match._id唯一标识最好) - 网格优化:添加了
mb-4(margin-bottom)让每个网格项之间有间距,用容器container包裹让内容更规整
如果你只想展示特定索引的项(比如0、5、8),也可以先判断数组长度足够再访问:
render() { const { matches } = this.state; return ( <div className="container mt-4"> <div className="row"> {matches.length > 0 && ( <div className="col-lg-4" style={{ backgroundColor: 'lavender' }}>{matches[0].season}</div> )} {matches.length > 5 && ( <div className="col-lg-4" style={{ backgroundColor: 'lavenderblush' }}>{matches[5].season}</div> )} {matches.length > 8 && ( <div className="col-lg-4" style={{ backgroundColor: 'lavender' }}>{matches[8].season}</div> )} </div> </div> ); }
这样就能避免报错,同时正确渲染数据啦!
内容的提问来源于stack exchange,提问作者stone rock
相关产品推荐
相关产品推荐

