React 精读笔记:从 JSX 的花括号到列表 key 的 5 个高频疑问

31 阅读2分钟

原文对应章节:Displaying Data – react.dev


1. 把变量/表达式塞进 JSX 的三种姿势

// 1. 纯文本
const name = 'React';
<h1>Hello, {name}!</h1>        // Hello, React!

// 2. 任意表达式
<h2>{2 + 2 === 4 ? '正确' : '错误'}</h2>

// 3. 函数调用
function formatDate(d) {
  return d.toLocaleDateString();
}
<p>Today is {formatDate(new Date())}.</p>

官方强调:

  • 花括号 {} 只能写在 JSX 标签内部属性值 里;
  • 不能直接写 if/for 语句,但可以用 三元、逻辑与、map 等表达式。

2. 渲染列表:为什么 key 必须是「兄弟之间唯一」

function Blog({ posts }) {
  const sidebar = (
    <ul>
      {posts.map(p =>
        <li key={p.id}>{p.title}</li>   // ✅ key 只在 <li> 兄弟间唯一即可
      )}
    </ul>
  );

  const content = posts.map(p =>
    <div key={p.id}>                   // ✅ 同样可以复用 p.id
      <h3>{p.title}</h3>
      <p>{p.content}</p>
    </div>
  );

  return (
    <>
      {sidebar}
      <hr />
      {content}
    </>
  );
}

官方提示:

  • key 不会作为 prop 传递给组件,因此 <Post key={id} id={id} /> 需要再传一次同名 prop ;
  • 不要用数组下标作为 key,除非列表不会重排。

3. 条件渲染的 4 种速写

写法场景示例
三元二选一{isLogin ? <Logout/> : <Login/>}
逻辑与显示/隐藏{show && <Modal/>}
立即执行函数复杂分支{(() => { ... })()}
提前 return组件级if (loading) return <Spinner/>;

4. 字符串模板 vs JSX:如何显示富文本

  • 普通文本:直接 {title}
  • HTML 字符串
    <div dangerouslySetInnerHTML={{ __html: htmlString }} />
    
    ⚠️ 必须确保内容安全,防止 XSS。
  • Markdown:先通过库(如 marked)转成 HTML,再用上一条方法渲染。

5. 常见报错 & 检查清单

报错信息原因正确姿势
Objects are not valid as a React child把对象/数组直接放进 {}只渲染基本类型或 map 成元素
Each child in a list should have a unique "key" prop忘了给 map 的元素加 key补充稳定且唯一的 key
Expected '}'JSX 里写了 if/for 语句改成三元或提前计算

小结脑图

显示数据
├── 插值 {}
│   ├── 文本
│   ├── 表达式
│   └── 函数调用
├── 列表渲染
│   ├── map
│   └── key(兄弟唯一)
├── 条件渲染
│   ├── 三元
│   ├── &&
│   └── 提前 return
└── 富文本
    ├── 字符串
    ├── HTML
    └── Markdown

下一篇官方文档对应章节:Adding Interactivity,我们会用 useState 让上面的列表可增删改。