React中如何基于map函数渲染含差异化元素的卡片?
React卡片组件中条件渲染差异化元素解决方案
我用React的map函数生成课程卡片列表,最后一张卡片包含new: '새강의'和sale: '할인중'两个差异化字段,同时还有折扣价字段discount,但不知道怎么在Section5Card组件里把这些内容渲染出来,项目用普通CSS文件而非styled-components,相关代码如下:
Section5Bottom.jsx
import React from 'react'; import "../section5.css"; import Section5Card from './Section5Card'; const array = [ { 'id' : '1', 'img' : "https://cdn.inflearn.com/public/courses/324119/course_cover/07c45106-3cfa-4dd6-93ed-a6449591831c/%E1%84%80%E1%85%B3%E1%84%85%E1%85%AE%E1%86%B8%205%20%E1%84%87%E1%85%A9%E1%86%A8%E1%84%89%E1%85%A1%204.png", 'title' : '실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발', 'name' : '김영한', 'star' : '5', 'comment' : '(1473)', 'price' : '₩88,000', 'people' : '+12400명', }, { 'id' : '2', 'img' : "https://cdn.inflearn.com/public/courses/324671/course_cover/638eee1a-6381-402d-a17b-3724751414f1/frontend-env-eng.png", 'title' : '프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..)', 'name' : '김정환', 'star' : '5', 'comment' : '(169)', 'price' : '₩69,300', 'people' : '+2000명', }, { 'id' : '3', 'img' : "https://cdn.inflearn.com/public/courses/329477/cover/80fb90fb-0212-4eec-8fb0-7875622b198e/329477-eng.png", 'title' : '애플 웹사이트 인터랙션 클론!', 'name' : '1분코딩', 'star' : '5', 'comment' : '(187)', 'price' : '₩77,000', 'people' : '+3200명', }, { 'id' : '4', 'img' : "https://cdn.inflearn.com/public/courses/327193/cover/010c8faf-bfc5-4c6a-9623-a68dc3b38697/327193-eng.png", 'title' : 'Slack 클론 코딩[백엔드 with NestJS + TypeORM]', 'name' : '조현영', 'star' : '4.5', 'comment' : '(58)', 'price' : '₩44,000', 'people' : '+1100명', }, { 'id' : '5', 'img' : "https://cdn.inflearn.com/public/courses/329477/cover/80fb90fb-0212-4eec-8fb0-7875622b198e/329477-eng.png", 'title' : '모바일 웹 퍼블리싱 포트폴리오 with Figma', 'name' : '코딩웍스(Coding Works)', 'star' : '0', 'comment' : '(0)', 'discount' : '₩132,000', 'price' : '₩92,400', 'people' : '+100명', 'new' : '새강의', 'sale' : '할인중' } ] function Section5Bottom() { return ( <div id='Section5Bottom'> { array.map((a, i) => { return ( <Section5Card products={a} key={i} /> ) }) } </div> ) } export default Section5Bottom;
Section5Card.jsx
import React from 'react'; import '../section5.css'; function Section5Card(props) { return ( <div id='Section5Card'> <img src={props.products.img} id="Section5CardImg" /> <div id='Section5CardTitle'> {props.products.title} </div> <div id='Section5CardName'> {props.products.name} </div> <div id='Section5CardComment'> {props.products.comment} </div> <div id='Section5CardPrice'> {props.products.price} </div> <div id='Section5CardPeople'> {props.products.people} </div> </div> ) } export default Section5Card;
解决方案
核心思路是通过条件渲染判断字段是否存在,存在则渲染对应元素,配合CSS实现视觉差异化:
1. 修改Section5Card组件,添加条件渲染逻辑
import React from 'react'; import '../section5.css'; function Section5Card(props) { const product = props.products; return ( <div id='Section5Card'> {/* 条件渲染标签组:有new/sale字段才显示 */} {(product.new || product.sale) && ( <div className="card-badges"> {product.new && <span className="badge new-badge">{product.new}</span>} {product.sale && <span className="badge sale-badge">{product.sale}</span>} </div> )} <img src={product.img} id="Section5CardImg" /> <div id='Section5CardTitle'>{product.title}</div> <div id='Section5CardName'>{product.name}</div> <div id='Section5CardComment'>{product.comment}</div> {/* 条件渲染折扣价:有discount字段则显示划掉的原价 */} <div id='Section5CardPrice'> {product.discount && <span className="original-price">{product.discount}</span>} {product.price} </div> <div id='Section5CardPeople'>{product.people}</div> </div> ) } export default Section5Card;
2. 在section5.css中添加差异化样式
/* 给卡片容器添加相对定位,让标签能基于卡片定位 */ #Section5Card { position: relative; /* 保留原有样式 */ } /* 标签容器:固定在卡片左上角 */ .card-badges { position: absolute; top: 8px; left: 8px; display: flex; gap: 4px; } /* 通用标签样式 */ .badge { padding: 2px 6px; border-radius: 4px; font-size: 12px; color: #fff; font-weight: bold; } /* 「새강의」标签样式 */ .new-badge { background-color: #2db400; } /* 「할인중」标签样式 */ .sale-badge { background-color: #ff4b4b; } /* 原价划掉样式 */ .original-price { text-decoration: line-through; color: #999; margin-right: 8px; font-size: 14px; }
关键说明
- 用
&&逻辑判断实现条件渲染:只有当字段存在且为真值时,才渲染对应元素 - 给卡片容器设置
position: relative,确保标签的绝对定位不会脱离卡片范围 - 折扣价通过
<span>包裹并添加删除线样式,清晰区分原价和现价
内容的提问来源于stack exchange,提问作者MontaKr
相关产品推荐
相关产品推荐

