JSX 编译成什么

const el = <h1 className="title">Hi {name}</h1>;

经过 Babel / SWC 编译后大概是:

const el = React.createElement('h1', { className: 'title' }, 'Hi ', name);

返回的 el 是一个普通对象,叫 React Element:

{
  type: 'h1',
  props: { className: 'title', children: ['Hi ', 'World'] },
  key: null, ref: null
}

JSX 不渲染,只是描述。React 拿到这棵元素树才决定怎么渲染。

Next.js / Vite 默认用新版 JSX transform(自动 import jsx-runtime),所以你不写 import React。但本质没变。

大写 vs 小写

<div>      → type: 'div'      (原生 HTML 元素,字符串)
<Header>   → type: Header     (组件,函数引用)

大小写决定行为。所以 function header() {...}<header /> 会被当成原生 <header> 标签——必有 bug。

children 是什么

children 是一个 prop,可以是字符串、元素、数组、函数:

<Card>
  <h1>标题</h1>
  <p>内容</p>
</Card>

// props.children = [<h1>...</h1>, <p>...</p>]

可以传函数(render prop 模式):

<List>{(item) => <Row data={item} />}</List>

class 为什么叫 className

class 是 JS 关键字。同样 forhtmlFor这是 JS 限制,不是 React 任性

属性命名

JSX 属性是 camelCaseonClicktabIndexmaxLength。原生 HTML 是 onclicktabindex——别混。

唯一例外:aria-*data-* 保持短横线(HTML 历史包袱)。

大括号里能写什么

<div>{anyJsExpression}</div>

表达式——求值后是字符串、数字、元素、数组、nullundefinedfalseif/for 等语句不行:

// ❌
<div>{if (x) return ...}</div>

// ✅
<div>{x ? <A /> : <B />}</div>
<div>{x && <A />}</div>          // x 为 0 时会渲染数字 0,注意
<div>{!!x && <A />}</div>        // 安全做法
<div>{list.map(i => <Row key={i.id} />)}</div>

key 不是装饰

key 让 React 在列表 diff 时认出哪个是哪个。错误的 key 等于"重新创建"——state 丢失、动画失效。

list.map((item, i) => <Row key={i} />)        // ❌ index 作 key,列表增删时全乱
list.map(item => <Row key={item.id} />)        // ✅ 用稳定 id

Fragment

return (
  <>
    <Header />
    <Main />
  </>
);

<></>React.Fragment 的语法糖——不渲染真实 DOM,只是把多个元素当一个返回。需要写 key 时不能用空写法,要 <Fragment key={...}>

dangerouslySetInnerHTML

设置原始 HTML,绕过 XSS 防护

<div dangerouslySetInnerHTML={{ __html: rawHtml }} />

名字带 dangerously 是故意吓人的——除非内容来源可信(如经过 DOMPurify 清洗的 markdown),别用。

  • JSX 表达式必须有单一根(或用 Fragment)
  • boolean / null / undefined / 数组不渲染,但 数字 0 会渲染——{count && <X />} 当 count=0 时屏幕上会出现 "0"
  • HTML 注释 <!-- --> 不行,要 {/* */}
  • 内联 style 是对象style={{ color: 'red' }},值用 camelCase(backgroundColor

→ 下一篇 组件分类与组合模式