🚀 React JSX 語法講解
1. 課程概述
本課程旨在系統講解 JSX(JavaScript XML) 的核心概念與實戰應用。JSX 是 React 的核心語法擴展,它允許我們在 JavaScript 中編寫類似 HTML 的結構,使得構建用戶界面變得直觀和高效。通過本課程,學生將從理解 JSX 的本質出發,逐步掌握其語法規則、表達能力、與 HTML 的差異,最終能夠熟練運用 JSX 構建動態、可復用的 React 組件。
2. 知識目標與實例佐證
知識目標 | 具體內容與實例佐證 | 對應代碼示例(簡略) |
---|---|---|
理解 JSX 的本質與編譯原理 | JSX 是 JavaScript 的語法擴展,不是字符串也不是 HTML,最終會被編譯(如通過 Babel)為 React.createElement() 函數調用。 | const element = <h1>Hello, JSX!</h1>; 編譯為: React.createElement('h1', null, 'Hello, JSX!'); |
掌握 JSX 的核心語法規則 | - 標簽必須閉合:<img /> - 屬性名使用 camelCase: className (代替 class ),htmlFor (代替 for ), onClick - 必須有一個根元素:用 <div> 或 <> (Fragment)包裹。 | <div className="container"><label htmlFor="name">Name:</label><img src="..."/></div> |
理解 JSX 中的表達式與語句 | 使用 {} 嵌入任何 JavaScript 表達式(變量、函數調用、運算、三元表達式等),但不能嵌入語句(如 if , for )。 | const name = 'Alice'; const element = <p>Hello, {name}! It's {new Date().toLocaleTimeString()}</p>; {isLoggedIn ? <LogoutButton /> : <LoginButton />} |
認識 JSX 與 HTML 的關鍵差異 | - JSX 是 JavaScript 的語法擴展,最終會轉換為 JavaScript 對象。 - 一些 HTML 屬性或標簽在 JSX 中可能不適用(如 <script> 、<style> 需謹慎使用)。- JSX 允許添加自定義行為(如事件處理函數)和通過屬性傳遞數據。 | <button onClick={() => alert('Clicked!')}>Click Me</button> <Welcome name="Alice" /> |
了解虛擬DOM與JSX的關系 | JSX 更像是描述 React 元素(虛擬DOM節點)結構和屬性的“藍圖”或“模板”。React 使用 JSX 來高效地創建和更新虛擬 DOM,然后通過對比(diffing)來決定如何最有效地更新真實 DOM。 | JSX 描述 UI 應該是什么樣子,而 React 負責將其高效地渲染和更新到頁面上。 |
3. 技能目標與實戰練習
技能目標 | 具體實踐與實例佐證 | 實戰代碼示例(僅供參考) |
---|---|---|
創建與渲染JSX元素 | 能夠編寫基本的JSX元素,并在React組件中返回它們。 | function Greeting() { return <h1>Hello, World!</h1>; } |
在JSX中嵌入表達式與進行運算 | 熟練使用 {} 嵌入變量、對象屬性、函數調用結果和進行各種運算。 | function UserInfo({ user, score }) { return <p>User: {user.name}, Score: {score * 10}</p>; } |
使用JSX進行條件渲染 | 掌握使用三元表達式和邏輯與(&& )運算符實現條件的條件渲染。 | function WelcomeMessage({ isLoggedIn, username }) { return ( <div> {isLoggedIn ? <h1>Welcome back, {username}!</h1> : <h1>Please log in.</h1>} {hasUnreadMessages && <p>You have unread messages!</p>} </div> ); } |
使用JSX進行列表渲染 | 掌握使用數組的 map() 方法渲染列表數據,并為每個列表項添加唯一的 key 屬性(通常使用數據id,而非索引)以提高渲染性能。 | function TodoList({ todos }) { return ( <ul> {todos.map(todo => ( <li key={todo.id}>{todo.text}</li> ))} </ul> ); } |
在JSX中綁定事件與處理交互 | 掌握為元素添加事件處理函數(如 onClick , onChange ),注意使用駝峰命名和傳遞函數引用(而非調用)。并能阻止默認事件行為。 | function Button() { function handleClick(e) { e.preventDefault(); alert('Clicked!'); } return <button onClick={handleClick}>Click Me</button>; } |
組合使用JSX與組件構建界面 | 能夠將JSX結構拆分為可復用的組件,并通過 props 向組件傳遞數據(包括基本類型、對象、數組甚至函數)來動態渲染內容。 | function App() { return ( <div> <Welcome name="Sara" /> <TodoList todos={todoItems} /> </div> ); } |
4. 綜合實戰案例:簡易任務卡片列表
下面是一個融合了多項技能目標的實戰示例,您可以在課堂上引導學生實現:
// 任務卡片組件 - 接收props,條件渲染,內聯樣式
function TaskCard({ title, description, completed, onToggle }) {const cardStyle = {border: '1px solid #ddd',borderRadius: '8px',padding: '16px',margin: '10px 0',backgroundColor: completed ? '#e8f5e9' : '#f9f9f9'};return (<div style={cardStyle}><h3>{title}</h3><p>{description}</p><p>Status: {completed ? '? Completed' : '? Incomplete'}</p><button onClick={onToggle}>{completed ? 'Mark Incomplete' : 'Mark Complete'}</button></div>);
}// 主應用組件 - 狀態管理,列表渲染,傳遞props
function TaskBoard() {const [tasks, setTasks] = useState([{ id: 1, title: 'Learn JSX', description: 'Complete the JSX tutorial', completed: true },{ id: 2, title: 'Build a React App', description: 'Create your first component', completed: false },{ id: 3, title: 'Practice State Management', description: 'Understand useState hook', completed: false }]);const handleToggleTask = (taskId) => {setTasks(tasks.map(task =>task.id === taskId ? { ...task, completed: !task.completed } : task));};return (<div><h1>Task Board</h1>{/* 條件渲染:顯示未完成任務數量 */}<p><strong>{tasks.filter(t => !t.completed).length}</strong> tasks remaining</p>{/* 列表渲染:使用map和key */}<div>{tasks.map(task => (<TaskCardkey={task.id} // 必須提供唯一的keytitle={task.title}description={task.description}completed={task.completed}onToggle={() => handleToggleTask(task.id)} // 傳遞函數作為prop/>))}</div></div>);
}
案例技能點解析:
- 組件與Props:
TaskCard
組件接收多個 props 來展示不同內容。 - 條件渲染:根據
completed
狀態改變背景色和顯示文本。 - 列表渲染與key:使用
map
渲染列表,并為每個TaskCard
提供唯一key
。 - 事件處理:點擊按鈕觸發
onToggle
函數,更新父組件狀態。 - State提升:狀態管理在父組件
TaskBoard
中,通過函數prop (handleToggleTask
) 與子組件通信。 - 內聯樣式:根據狀態動態計算樣式對象。
- JSX表達式:在
{}
內進行計算和條件判斷。
5. 課后練習與挑戰
- 基礎練習:創建一個
UserProfile
組件,接受name
、age
和hobbies
(數組)作為 props,并渲染出來。為愛好列表添加 key。 - 進階挑戰:在上述任務列表中添加新增任務的功能,并實現本地存儲(localStorage)持久化任務數據。
- 思考題:為什么在列表渲染中,使用數組索引 (index) 作為
key
在某些情況下可能會帶來問題?