3.2 JSX 语法详解


3.2 JSX 语法详解

本节摘要:JSX 是在 JavaScript 里书写界面的语法糖,本质会被编译成普通函数调用。学会"什么时候用括号、怎么插值、表达式与语句的边界、为什么防 XSS"这四件事,就掌握了 JSX 的八成日常用法。

本节阅读目标
阅读完本节,你应当能够:

  1. 说清 JSX 何以"像 HTML 却终究是 JS"。
  2. 正确使用花括号插值,区分表达式与语句。
  3. 解释 JSX 默认转义带来的防注入保证,并说明何时该用干预。

一、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 惯用法

列表与条件渲染在 JSX 里都要靠表达式。常见三种:

  • 三元:两种情况互斥切换。
  • 与运算:只判断"要不要渲染"这一种情况。
  • map 生列表:数据数组变元素数组,且每项要 key。
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 从写到渲染的编译链路

图:JSX 语法糖的编译与虚拟 DOM 物化

图:JSX 语法糖的编译与虚拟 DOM 物化

七、易错点小结

  • 参数顺序与括号:返回多行 JSX 时用小括号包住,避免自动分号插值踩坑。
  • 属性名风格:JSX 里事件与部分属性走驼峰,别照搬 HTML 小写。
  • 保留字冲突:class 与 for 这类保留字要用替代写法(如 className、htmlFor)。

八、一段话串起 JSX 的使用直觉

如果只让记住一句,是这样的:JSX 里只要看见花括号,你就站在 JavaScript 环境里;花括号外是"长得像 HTML"的骨架,花括号里是"任何有返回值的表达式"。遇到"要不要显示"就抛一个三元或与表达式,遇到"一串数据"就抛一个 map 出来的数组,遇到"出错了,是语句"就退回去想想怎么改写成表达式。你不需要背 JSX 的每一种写法,只要把这条边界感记住,绝大多数日常代码自然写得顺。

团队评审里常出现的一个分歧是"要不要过度依赖 JSX 表达式嵌套"。比如一个三行嵌套的三元会把可读性毁掉,比稿时宁可拆出一个小变量、或提前算好要渲染的节点,再放到 JSX 里。这条原则跟 2.1 节的接口评审一脉相承:能表达清楚比炫技重要,JSX 提供的是表达力,不是用来堆嵌套的借口。

一段容易让新同学懵的"两义性"

JSX 里有两个容易造成"两个值都对,却出不同结果"的写法,最好一开始就拎清。一是 null 与空字符串都"不显示",但它们的语义不同,调试"为什么这块没出现"时要分清是负责没东西还是真的没数据。二是 false0 在条件渲染里的差异很阴人——{count && <span>有值</span>} 当 count 等于 0 时,渲染的不是"隐藏"而是数字 0 本身,因为 0 是真值表达式的结果。想只控制显隐,用三元或显式判断更稳。这两处是 JSX 初学者最容易栽的"显示不出来"或"多出一个怪字符"的头号根源,记住它们,比背完整份规则更有用。

让 props 与样式的传法也顺手起来

JSX 另一处高频写法是"一次把一袋子属性丢进去"。当你要把一组数据整体传给某个子组件时,用展开运算符而不是逐个手写,既省字又避免漏传:

const base = { name: '阿明', avatar: '/a.png' }; <User {...base} /> // 等价于一次传 name、avatar 两个属性

同理,样式对象这种"整袋进出"的数据也适合先算好变量再放进去:style={{ color: active ? '#0af' : '#333' }} 外层花括号表示"这是 JSX 表达式",内层花括号是普通的对象字面量,两层花括号叠在一起常让新同学发懵。记住"一层是表达式边界、一层是对象字面量"就能一眼看懂。这类"整袋传"的写法在组件复用里尤其常见——第 5 章讲组件通信时,你会频繁看到用 {...item} 把一行数据摊给卡片组件。JSX 的展开与对象两层花括号,是先养成习惯不吃亏的一部分。

本节要点回顾

  • 定位:JSX 是编译成函数调用的语法糖,不是模板。
  • 插值入口:单层花括号内放表达式,语句要另想办法。
  • 分支与列表:靠三元、与运算、map 表达,别写语句。
  • 安全网:默认转义防注入,需要时再显式过 HTML。
  • 四个易错点:括号、驼峰、保留字、语义边界。

JSX 讲透了,下一节看组件本身——React 组件有函数式与类式两种皮囊,我们逐一比较、明确推荐哪种。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U