Next.js中根据JSON的image字段在左右卡片展示数据
问题描述
我通过getServerSideProps()获取了一段JSON数据,其中部分条目的image字段为空:
[ { "date": "03/11/2022, 18:45:24", "description": "Want to know more about simping and how to profit from it? Simps can make you a lot money on OnlyFans and this article details how to get and keep more simps.", "id": "a8cf9c135192d426511712242a2bb7e27bf70e39388baa61190fe0af24f8291c", "image": "", "link": "https://seobounty.com/the-ultimate-guide-to-simping-and-why-men-simp/", "tag": "OnlyFans Advertising Guide", "title": "The Ultimate Guide to Simping and Why Men Simp" }, { "date": "02/02/2022, 20:10:21", "description": "Google Paid Search ads are one of the best digital advertising methods to target people who are actively searching and in the market for the products or services that your business offers. However, if you’re not experienced with Google Ads then you may fin", "id": "29dc9f038b5ee4bd68e96298627d5806c72e1f927b73077d725a86239a97d94f", "image": "https://activebusinessgrowth.ca/wp-content/uploads/2022/02/TN-23-Improve-ads.png", "link": "https://activebusinessgrowth.ca/5-ways-to-drastically-improve-your-google-ads/", "tag": "Digital Marketing", "title": "5 Ways To Drastically Improve Your Google Ads" } ]
需求:
- 带
image字段的内容放在左侧卡片,image为空的放在右侧卡片 - 两张卡片并列显示
我编写了如下代码,但目前仅能显示带图片的卡片,空图片的卡片无法显示:
export default function Home({data}) { return ( <div className={styles.container}> <Head> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> <main className={styles.main}> <h1 className={styles.title}> title </h1> <p className={styles.description}> description </p> <div className={styles.grid}> {data.map(result =>{ const{id, title, link, date, image, description, tag} = result; if(result.image !=="") { return( <div key={id} className={styles.card}> <h2><a href={link}>{title}</a></h2> <h4>{date}</h4> <div> <a href = {link}> <img src={image} alt="" width="40%" height="auto"></img> </a> </div> <h3>{description}</h3> <p>{tag}</p> <p>root domain</p> </div> ) } else if(result.image === "") { return ( <div key={id} className={styles.card}> <h2><a href={link}>{title}</a></h2> <h4>{date}</h4> <p>{tag}</p> <p>root domain</p> </div> ) } })} </div>
期望实现两张卡片并列,右侧卡片无图的效果。
问题分析与解决
问题原因
代码逻辑本身无错误,核心问题出在CSS布局设置:
styles.grid或styles.card的宽度、溢出规则可能导致无图卡片被挤出视口或隐藏- 提供的代码存在未闭合的JSX标签,可能引发渲染异常
修复方案
1. 补全代码结构并优化逻辑
将数据拆分为有图、无图两组,分别渲染到左右容器,更贴合需求且便于控制布局:
import Head from 'next/head' import styles from '../styles/Home.module.css' export default function Home({ data }) { // 拆分数据为有图、无图两组 const hasImageItems = data.filter(item => item.image !== "") const noImageItems = data.filter(item => item.image === "") return ( <div className={styles.container}> <Head> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> <main className={styles.main}> <h1 className={styles.title}> title </h1> <p className={styles.description}> description </p> {/* 外层行容器实现左右并列 */} <div className={styles.cardRow}> {/* 左侧:带图卡片容器 */} <div className={styles.cardColumn}> {hasImageItems.map(result => { const { id, title, link, date, image, description, tag } = result; return ( <div key={id} className={styles.card}> <h2><a href={link}>{title}</a></h2> <h4>{date}</h4> <div> <a href={link}> <img src={image} alt={title} width="40%" height="auto"></img> </a> </div> <h3>{description}</h3> <p>{tag}</p> <p>root domain</p> </div> ) })} </div> {/* 右侧:无图卡片容器 */} <div className={styles.cardColumn}> {noImageItems.map(result => { const { id, title, link, date, tag } = result; return ( <div key={id} className={styles.card}> <h2><a href={link}>{title}</a></h2> <h4>{date}</h4> <p>{tag}</p> <p>root domain</p> </div> ) })} </div> </div> </main> </div> ) } export async function getServerSideProps() { // 数据获取逻辑,示例直接返回给定JSON const data = [ { "date": "03/11/2022, 18:45:24", "description": "Want to know more about simping and how to profit from it? Simps can make you a lot money on OnlyFans and this article details how to get and keep more simps.", "id": "a8cf9c135192d426511712242a2bb7e27bf70e39388baa61190fe0af24f8291c", "image": "", "link": "https://seobounty.com/the-ultimate-guide-to-simping-and-why-men-simp/", "tag": "OnlyFans Advertising Guide", "title": "The Ultimate Guide to Simping and Why Men Simp" }, { "date": "02/02/2022, 20:10:21", "description": "Google Paid Search ads are one of the best digital advertising methods to target people who are actively searching and in the market for the products or services that your business offers. However, if you’re not experienced with Google Ads then you may fin", "id": "29dc9f038b5ee4bd68e96298627d5806c72e1f927b73077d725a86239a97d94f", "image": "https://activebusinessgrowth.ca/wp-content/uploads/2022/02/TN-23-Improve-ads.png", "link": "https://activebusinessgrowth.ca/5-ways-to-drastically-improve-your-google-ads/", "tag": "Digital Marketing", "title": "5 Ways To Drastically Improve Your Google Ads" } ] return { props: { data } } }
2. 调整CSS样式实现并列布局
修改Home.module.css,使用Flexbox实现左右并列:
.container { padding: 0 2rem; } .main { min-height: 100vh; padding: 4rem 0; flex: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; } .title a { color: #0070f3; text-decoration: none; } .description { margin: 4rem 0; line-height: 1.5; font-size: 1.5rem; } /* 外层行容器,控制左右并列 */ .cardRow { display: flex; gap: 2rem; width: 100%; max-width: 1200px; } /* 左右列容器,各占50%宽度 */ .cardColumn { flex: 1; } .card { padding: 1.5rem; border: 1px solid #eaeaea; border-radius: 10px; background: white; box-shadow: 0 2px 8px rgba(0,0,0,0.1); } .card h2 { margin: 0 0 1rem 0; font-size: 1.5rem; } .card h4 { color: #666; margin: 0 0 1rem 0; } .card img { margin: 1rem 0; } .card p { margin: 0.5rem 0; }
关键改进点
- 拆分数据分组渲染,逻辑更清晰,便于维护
- 补全所有JSX闭合标签,避免渲染异常
- 使用Flexbox实现稳定的左右并列布局,确保两张卡片同时显示
- 补充完整的
getServerSideProps实现,保证数据正常获取
内容的提问来源于stack exchange,提问作者Mi Yahn
相关产品推荐
相关产品推荐

