本节摘要:JSX 是在 JavaScript 里书写界面的语法糖,本质会被编译成普通函数调用。学会"什么时候用括号、怎么插值、表达式与语句的边界、为什么防 XSS"这四件事,就掌握了 JSX 的八成日常用法。
本节阅读目标
阅读完本节,你应当能够:
很多人第一眼以为 JSX 是模板字符串,其实它是被编译成 JavaScript 函数调用的语法糖。一个组件:
const welcome = <h1>你好,{user}</h1>;
会被编译成类似"调用创建元素方法"的形式,最终产物是一棵普通对象树——这正是第 2.2 节虚拟 DOM 的原始素材。这一点解释了 JSX 的全部"任性":因为它终究是 JS,所以能在里面写任何表达式。
想在 JSX 里放进动态值,用单层花括号:
function Profile({ name, avatar }) { return ( <figure> <img src={avatar} alt={name} /> <figcaption>{name.toUpperCase()}</figcaption> </figure> ); }
花括号内部可以是变量、函数调用、三元等一切有返回值的表达式。要注意边界:花括号内是语句不行(比如 if),这时应该换写法,见下节。
JSX 是表达式,内部也只认表达式。遇到"需要分支"的情况,用三元、与运算或预计算:
function Status({ isOn }) { return <p>状态:{isOn ? '开启' : '关闭'}</p>; }
别写 { if (isOn) ... },这是语句,会直接报错。习惯是用三元表达分支,用 map 表达列表(回顾 2.5 节列表渲染)。
列表与条件渲染在 JSX 里都要靠表达式。常见三种:
function ProductList({ products }) { return ( <ul> {products.length > 0 ? products.map((p) => <li key={p.id}>{p.name}</li>) : '暂无商品'} </ul> ); }
这里同时用到了三元(空态兜底)和 map(列表),对应 2.5 节的两种结构。
JSX 默认把插值的文本转义,恶意注入的标签会被当作纯文本显示,而不是被执行。这是它比很多手动拼接 HTML 的方案更安全的地方。只有当你确实需要渲染 HTML 片段时,才用那些显式地把字符串当 HTML 的接口(并确保内容是可信的),其余保持默认转义即可。

如果只让记住一句,是这样的:JSX 里只要看见花括号,你就站在 JavaScript 环境里;花括号外是"长得像 HTML"的骨架,花括号里是"任何有返回值的表达式"。遇到"要不要显示"就抛一个三元或与表达式,遇到"一串数据"就抛一个 map 出来的数组,遇到"出错了,是语句"就退回去想想怎么改写成表达式。你不需要背 JSX 的每一种写法,只要把这条边界感记住,绝大多数日常代码自然写得顺。
团队评审里常出现的一个分歧是"要不要过度依赖 JSX 表达式嵌套"。比如一个三行嵌套的三元会把可读性毁掉,比稿时宁可拆出一个小变量、或提前算好要渲染的节点,再放到 JSX 里。这条原则跟 2.1 节的接口评审一脉相承:能表达清楚比炫技重要,JSX 提供的是表达力,不是用来堆嵌套的借口。
JSX 里有两个容易造成"两个值都对,却出不同结果"的写法,最好一开始就拎清。一是 null 与空字符串都"不显示",但它们的语义不同,调试"为什么这块没出现"时要分清是负责没东西还是真的没数据。二是 false 与 0 在条件渲染里的差异很阴人——{count && <span>有值</span>} 当 count 等于 0 时,渲染的不是"隐藏"而是数字 0 本身,因为 0 是真值表达式的结果。想只控制显隐,用三元或显式判断更稳。这两处是 JSX 初学者最容易栽的"显示不出来"或"多出一个怪字符"的头号根源,记住它们,比背完整份规则更有用。
JSX 另一处高频写法是"一次把一袋子属性丢进去"。当你要把一组数据整体传给某个子组件时,用展开运算符而不是逐个手写,既省字又避免漏传:
const base = { name: '阿明', avatar: '/a.png' }; <User {...base} /> // 等价于一次传 name、avatar 两个属性
同理,样式对象这种"整袋进出"的数据也适合先算好变量再放进去:style={{ color: active ? '#0af' : '#333' }} 外层花括号表示"这是 JSX 表达式",内层花括号是普通的对象字面量,两层花括号叠在一起常让新同学发懵。记住"一层是表达式边界、一层是对象字面量"就能一眼看懂。这类"整袋传"的写法在组件复用里尤其常见——第 5 章讲组件通信时,你会频繁看到用 {...item} 把一行数据摊给卡片组件。JSX 的展开与对象两层花括号,是先养成习惯不吃亏的一部分。
JSX 讲透了,下一节看组件本身——React 组件有函数式与类式两种皮囊,我们逐一比较、明确推荐哪种。