JSX Rendering Article List
In this chapter, you will learn how to use JSX expressions to render JS data into the UI, allowing the blog homepage to display a list of article cards.
{} Embedding Expressions in JSX
In JSX,curly braces {}are the entry point into the JavaScript world.
Any JS expression can be placed inside curly braces: variables, operations, function calls, ternary expressions, etc.
Example
const blogTitle = 'EXAMPLE Front-end Notes'
const author = 'Xiao Ming'
return (
<div>
<h1>{blogTitle}</h1>
<p>Author:{author}</p>
<p>Current time:{new Date().toLocaleDateString()}</p>
<p>Welcome message:{author ?`Hello, ${author}` : 'Welcome, visitor'}</p>
</div>
)
}
The page will render:
EXAMPLE 前端笔记 作者:小明 当前时间:2024/5/15 欢迎语:你好,小明
Curly braces can only containexpressions(code that evaluates to a value), not statements. For example,
{if (condition) ...}is invalid, but{condition ? 'A' : 'B'}is valid.
Attribute Binding
HTML attributes in JSX need to be dynamically bound using curly braces.
Example
const coverUrl = '/images/react-cover.png'
const linkUrl = '/post/1'
return (
<div>
{/* Dynamic attribute: curly braces bind a JS variable */}
<img src={coverUrl} alt="Article cover" />
<a href={linkUrl}>Read more</a>
{/* Note: class must be written as className */}
<div className="card active">Card content</div>
{/* style accepts an object, with property names in camelCase */}
<div style={{ color: '#427DB8', fontSize: '16px' }}>
Green text
</div>
</div>
)
}
| HTML | JSX | Explanation |
|---|---|---|
class="btn" | className="btn" | class is a JS reserved word |
style="color: red" | style={{ color: 'red' }} | Receives an object, property names in camelCase |
src="xxx.html" | src={variable} | Dynamic values use curly braces |
onclick="fn()" | onClick={fn} | Event names in camelCase, pass a function reference |
List Rendering: array.map()
React does not have directives like Vuev-fordoes.
To render lists in JSX, directly use JavaScript'sarray.map()method.
Example
// Use an array of JS objects to simulate article data
const articles = [
{
id: 1,
title: 'The Complete Guide to Getting Started with React',
summary: 'Learn React Hooks from scratch, covering core concepts such as useState, useEffect, and more.',
date: '2024-05-10',
category: 'React',
cover: '/images/react.png'
},
{
id: 2,
title: 'Detailed Explanation of JavaScript Asynchronous Programming' 66) 'Understand Promise, async/await, event loop, and microtask queue in one article.',
summary: 'One article to fully understand Promise, async/await, event loop, and microtask queue.',
date: '2024-05-08',
category: 'JavaScript',
cover: '/images/js.png'
},
{
id: 3,
title: 'CSS Grid Layout in Practice',
summary: 'Easily implement complex responsive layouts with CSS Grid.',
date: '2024-05-05',
category: 'CSS',
cover: '/images/css.png'
}
]
return (
<div className="article-list">
{/* map iterates through the array, returning a piece of JSX for each item */}
{articles.map(article => (
<div key={article.id} className="card">
<img src={article.cover} alt={article.title} />
<div className="card-body">
<span className="category">{article.category}</span>
<h3>{article.title}</h3>
<p>{article.summary}</p>
<span className="date">{article.date}</span>
</div>
</div>
))}
</div>
)
}
The Importance of the key Attribute
keyis a unique identifier assigned to each element in a list, helping React identify which elements have changed.
Without key, React uses an "in-place update" strategy, which may cause state confusion and performance degradation.
| key Value | Consequence |
|---|---|
| Unique id (recommended) | Correctly tracks each element, efficient Diff |
| Array index | Inserting/deleting may cause input field content to be disordered |
| No key | Console warning, poor performance |
Always add aunique and stablekey to the JSX returned by map. Do not use index as the key, especially when list items may be added, removed, or reordered.
Conditional Rendering
React has no v-if, but there are three ways to implement conditional rendering.
Example
const articles = []
const isLoading = false
return (
<div>
{/* Method 1: Ternary expression — suitable for choosing between two */}
{isLoading ? (
<p>Loading, please wait...</p>
) : (
<p>Loading complete!</p>
)}
{/* Method 2: && short-circuit — suitable for "show if condition is true, don't show if not" */}
{articles.length === 0 && <p>No articles yet, stay tuned.</p>}
{/* Method 3: if/else at the top level of a component — suitable for complex multi-condition logic */}
{articles.length > 0 ? (
<div>
{articles.map(a => <div key={a.id}>{a.title}</div>)}
</div>
) : (
<p>No data</p>
)}
</div>
)
}
Comparison of Three Conditional Rendering Approaches
| Approach | Syntax | Applicable Scenario |
|---|---|---|
Ternary? : | {cond ? <A /> : <B />} | Choose one of two, must return something |
Short-circuit&& | {cond && <A />} | Show if present, don't show if not |
| Early if check | Store JSX in a variable before return | Complex conditional branching scenarios |
&&Short-circuit has a pitfall: when the condition is the number 0, it renders "0". It is recommended that the&&left side always be a boolean:{list.length > 0 && ...}instead of{list.length && ...}。
Hands-on: Complete Blog Homepage
Example
import './App.css'
function App() {
const articles = [
{
id: 1, title: 'The Complete Guide to Getting Started with React',
summary: 'Learn React Hooks from scratch, covering core concepts such as useState, useEffect, and more.',
date: '2024-05-10', category: 'React', cover: '/images/react.png'
},
{
id: 2, title: 'Detailed Explanation of JavaScript Asynchronous Programming',
summary: 'Understand Promise, async/await, event loop, and microtask queue in one article.',
date: '2024-05-08', category: 'JavaScript', cover: '/images/js.png'
},
{
id: 3, title: 'CSS Grid Layout in Practice',
summary: 'Easily implement complex responsive layouts with CSS Grid.',
date: '2024-05-05', category: 'CSS', cover: '/images/css.png'
}
]
return (
<div className="app">
<header className="navbar">
<h1 className="logo">EXAMPLE Blog</h1>
<nav>
<a href="/">Home</a>
<a href="#">About</a>
</nav>
</header>
<main className="container">
<h2 className="section-title">Latest Articles</h2>
{/* Conditional rendering: show articles if they exist, otherwise show an empty state */}
{articles.length === 0 ? (
<p className="empty-tip">No articles yet, stay tuned.</p>
) : (
<div className="article-grid">
{/* List rendering: map iterates through the array */}
{articles.map(article => (
<div key={article.id} className="article-card">
<img src={article.cover} alt={article.title} className="card-cover" />
<div className="card-content">
<span className="card-category">{article.category}</span>
<h3 className="card-title">{article.title}</h3>
<p className="card-summary">{article.summary}</p>
<span className="card-date">{article.date}</span>
</div>
</div>
))}
</div>
)}
</main>
<footer className="footer">
<p>© 2024 EXAMPLE Blog. Powered by React.</p>
</footer>
</div>
)
}
export default App
Example
.section-title {
font-size: 24px;
margin-bottom: 20px;
color: #333;
}
.article-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
.article-card {
background: #fff;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
transition: transform 0.2s, box-shadow 0.2s;
cursor: pointer;
}
.article-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
.card-cover {
width: 100%;
height: 180px;
object-fit: cover;
}
.card-content {
padding: 16px;
}
.card-category {
display: inline-block;
padding: 2px 10px;
background: #e3f2fd;
color: #1976d2;
border-radius: 12px;
font-size: 12px;
margin-bottom: 8px;
}
.card-title {
font-size: 18px;
margin-bottom: 8px;
color: #222;
}
.card-summary {
font-size: 14px;
color: #666;
line-height: 1.6;
margin-bottom: 12px;
}
.card-date {
font-size: 12px;
color: #999;
}
.empty-tip {
text-align: center;
color: #999;
padding: 60px 0;
font-size: 16px;
}
Chapter Summary
In this chapter, you learned four core operations in JSX:{}Embedding expressions, attribute binding (className / style),map()List rendering + key, conditional rendering (ternary / short-circuit).
At this point, the blog homepage can dynamically render article cards based on JS data.
Additional Extensions