agentmentoragentmentor

第 05 节:条件和列表:把数据渲染成界面

本节 objectives:

  • 能用条件表达式控制某块 UI 是否显示。
  • 能用 map() 把数组渲染成列表。
  • 能解释列表里的 key 为什么不能随便省。

先修:state、事件和 JSX 表达式 | 上一节 << 04 | 下一节 06 >>

真实界面很少只有一条直线

组件通常要回答两个问题:现在显示哪一种状态?这一组数据每一项怎么显示?React 官方文档把条件渲染和列表渲染分开讲,但它们在实际组件里常常连在一起:有数据就显示列表,没数据就显示空状态。12

这节把 state、数组和 JSX 放到同一张桌上。

讲解

条件渲染可以用三元表达式:

jsx
{isLoading ? <p>加载中...</p> : <CourseList />}

也可以用 && 显示一小块可选 UI:

jsx
{error && <p role="alert">{error}</p>}

列表渲染常用 JavaScript 的 map()。MDN 定义 map() 会对数组每个元素调用函数,并返回一个新数组。3 在 React 里,这个新数组通常是一组 JSX 元素:

jsx
const lessons = ["组件", "JSX", "Props"];
return (  <ul>    {lessons.map((lesson) => (      <li key={lesson}>{lesson}</li>    ))}  </ul>);

key 帮 React 识别列表项的身份。官方列表文档要求每个数组项有稳定 key,这样插入、删除、重排时 React 才能正确匹配元素。2

跟我做一遍(worked example)

需求:显示课程任务列表。如果没有任务,显示空状态。

jsx
const tasks = [  { id: "c1", title: "写第一个组件", done: true },  { id: "c2", title: "练 JSX", done: false },  { id: "c3", title: "传 props", done: false },];
function TaskOverview() {  if (tasks.length === 0) {    return <p>还没有任务。</p>;  }
  return (    <ul>      {tasks.map((task) => (        <li key={task.id}>          {task.done ? "✓" : "○"} {task.title}        </li>      ))}    </ul>  );}

为什么用 task.id 做 key:标题可能会改,数组位置也可能会变。稳定 id 才代表这条任务本身。

换你补全(faded example)

补全一个消息列表。空状态和 key 是这题的关键判断点。

jsx
function MessageList({ messages }) {  if (messages.length === 0) {    return ________;  }
  return (    <ul>      {messages.map((message) => (        <li key={________}>          <strong>{message.from}</strong>: {message.text}        </li>      ))}    </ul>  );}

参考答案:

jsx
if (messages.length === 0) {  return <p>暂无消息。</p>;}
// ...<li key={message.id}>

如果数据没有 id,先补数据模型,不要默认用数组 index。index 在只追加且不重排的静态列表里勉强可用,但初学阶段先养成稳定 id 的习惯。

小结 + 通向下一节

条件渲染负责"显示哪一块",列表渲染负责"这一组怎么展开"。稳定 key 是列表的身份牌。

下一节看 effects。它不是用来计算所有东西的,而是用来和 React 外面的系统同步。

Footnotes

  1. Conditional Rendering — https://react.dev/learn/conditional-rendering

  2. Rendering Lists — https://react.dev/learn/rendering-lists 2

  3. Array.prototype.map() — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

练习

Level 1: 写一个 ReadingList 组件,接收 books 数组 props,渲染书名列表。空数组时显示"还没有书"。

提示 1

先把数组写成固定常量。

提示 2

再用 map() 渲染。

提示 3

最后加空状态和单项状态。

自评