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

function HomePage() {
  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

function ArticleCard() {
  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>
  )
}
HTMLJSXExplanation
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

function ArticleList() {
  // 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 ValueConsequence
Unique id (recommended)Correctly tracks each element, efficient Diff
Array indexInserting/deleting may cause input field content to be disordered
No keyConsole 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

function ArticlePage() {
  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

ApproachSyntaxApplicable 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 checkStore JSX in a variable before returnComplex 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

// File path: src/App.jsx
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

/* File path: src/App.css append the following styles */
.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