使用Bulma与Next.js(fetch拉取数据)创建3列卡片网格的问题
问题原因及解决方法
核心问题点
- 变量名不匹配:
getStaticProps返回的props字段为number,但组件接收时写的是numbers,导致数据获取异常 - 遍历逻辑错误:将数组按3个一组拆分后,内层遍历仍使用了完整的
numbers数组,导致每一行都渲染了全部卡片 - 未指定列宽:Bulma栅格为12格,要固定每行3列需要给每列添加
is-4类名,保证每列宽度为1/3
修正后的完整代码
import Head from "next/head"; import Image from "next/image"; import styles from "../styles/Home.module.css"; export const getStaticProps = async () => { const res = await fetch("http://localhost:3000/lorem.json"); const data = await res.json(); console.log(data); return { props: { numbers: data }, // 修改变量名和组件接收一致 }; }; const splitEvery = (array, length) => array.reduce((result, item, index) => { if (index % length === 0) result.push([]); result[Math.floor(index / length)].push(item); return result; }, []); const Home = ({ numbers }) => { // 兜底避免数据为空时报错 if (!numbers) return <div>加载中</div> return ( <div className="container p-5"> {splitEvery(numbers, 3).map((group, groupIndex) => ( <div className="columns" key={groupIndex}> {/* 内层遍历当前分组的3条数据,而非完整的numbers数组 */} {group.map((number) => ( <div className="column is-4" key={number.id}> <div className="card"> <div className="card-content"> <p className="title is-4">💠 {number.name}</p> </div> </div> </div> ))} </div> ))} </div> ); }; export default Home;
效果说明
- 修正前布局:

- 修正后即可达到预期的每行3张卡片布局:

可选简化方案
不用手动拆分数组,直接利用Bulma的多行列属性即可自动实现每行3列布局,代码更简洁:
const Home = ({ numbers }) => { if (!numbers) return <div>加载中</div> return ( <div className="container p-5"> <div className="columns is-multiline"> {numbers.map((number) => ( <div className="column is-4" key={number.id}> <div className="card"> <div className="card-content"> <p className="title is-4">💠 {number.name}</p> </div> </div> </div> ))} </div> </div> ); };
内容的提问来源于stack exchange,提问作者Ava Juan
相关产品推荐
相关产品推荐

