JSX 是 React 中最核心的一个概念,它也是区别于 Vue 最核心的一个概念 (Vue 现也已支持 JSX 语法);
JSX 全称 JavaScript And XML,是一种在 JavaScript 中编写 HTML 代码片段的语法协议,不过这种协议同样回归到编译阶段,jsx 最终通过编译转为 js 以在运行时工作;
在 React 应用中编写的 jsx 会先通过编译工具转换为 React 提供的运行时方法,从而在应用执行时工作;jsx -> _jsx -> jsxProd -> createElement
React 19 自动处理 JSX 转换,不再需要手动导入 React;
JSX 的基本示例
-
以下是一个简单的 JSX 示例:
import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')); root.render(<h1>Hello, world!</h1>);
-
在这个例子中,
<h1>Hello, world!</h1>
是 JSX,它表示一个包含文本 “Hello, world!” 的 h1 标签;
JSX 语法
JSX 表达式
-
可以在 JSX 中使用 JavaScript 表达式,用大括号 {} 包裹:
-
大括号内可以是 变量、字符串、数组、函数调用 等任意 js 表达式;
- 情况一:当变量是 Number、String、Array 类型时,可以直接显示;
- 情况二:当变量是 null、undefined、Boolean 类型时内容为空,如果希望可以显示,那么需要转成字符串;
- 情况三:对象类型不能作为子元素 (not valid as a React child);
function UserInfo() { const name = "Alice"; const age = 25; return ( <div> <p>Name: {name}</p> <p>Age: {age}</p> <p>Next year: {age + 1}</p> </div> ); }
JSX 属性
-
属性可以使用字符串字面量或 JavaScript 表达式:
function Avatar() { const avatarUrl = "https://example.com/avatar.jpg"; const altText = "User Avatar"; return ( <img src={avatarUrl} alt={altText} className="avatar" // 注意:class 改为 className style={{ width: 100, height: 100 }} // 内联样式是对象 /> ); }
JSX 事件
-
React 事件的命名采用小驼峰式 (camelCase),而不是纯小写;
-
需要通过 {} 传入一个事件处理函数,这个函数会在事件发生时被执行;
function Card() { const fn = () => alert('Clicked!'); return ( <div className="card"> <h2>Card Title</h2> <p>This is the card content.</p> <button onClick={fn}>Click Me</button> </div> ); }
JSX 条件渲染
-
在 JSX 中可以使用条件表达式:
function WelcomeMessage({ isLoggedIn }) { return ( <div> {isLoggedIn ? ( <h1>Welcome back!</h1> ) : ( <h1>Please sign in.</h1> )} </div> ); } // 或者使用逻辑与运算符 function Notification({ hasUnread }) { return ( <div> {hasUnread && <span className="badge">New</span>} </div> ); }
JSX 列表渲染
-
使用 map() 渲染列表:
-
列表的 key,在列表展示的 jsx 中添加一个 key,用于虚拟 dom 更新;
function TodoList() { const todos = [ { id: 1, text: 'Learn React' }, { id: 2, text: 'Build a project' }, { id: 3, text: 'Deploy to production' } ]; return ( <ul> {todos.map(todo => ( <li key={todo.id}>{todo.text}</li> ))} </ul> ); }
片段 (Fragments)
-
使用 <></> 或 Fragment 包裹多个元素,类似与 vue 中的 template 并不会被渲染出来:
function Columns() { return ( <> <td>Column 1</td> <td>Column 2</td> </> ); }
JSX 与 HTML 的区别
-
属性名使用 camelCase:className 而不是 class;
-
事件处理:onClick 而不是 onclick;
-
样式是对象:
style={{ color: 'red' }}
; -
必须闭合标签;
JSX 转换原理
-
JSX 不能直接在浏览器中运行,需要通过编译工具 (如 Babel) 转换为纯 JavaScript;Babel 是一个 JavaScript 编译器,可以将 JSX 和其他新语法转换为兼容性更好的旧版本 JavaScript;
-
以下是 JSX 转换为 JavaScript 的过程:
JSX 代码
const element = <h1>Hello, world!</h1>;
转换后的 JavaScript 代码
import { jsx as _jsx } from "react/jsx-runtime";
var element = /*#__PURE__*/ _jsx("h1", {
children: "Hello, world!"
});
React 运行时
var element = React.createElement('h1', null, 'Hello, world!');
React✍️ 入门
上一篇