二、 React 核心概念 React 核心概念详解与实践 一、 JSX (JavaScript XML) JSX 是一种 JavaScript 的语法扩展,允许你在 JavaScript 代码中编写类似 HTML 的结构。它并非真正的 HTML,而是会被 Babel 等工具编译成 JavaScript 代码,最终生成 React 组件。 1.1 JSX 的优势 声明式语法: JSX 使得 UI 结构更清晰,易于阅读和维护。 类型安全: JSX 可以与 TypeScript 等类型检查器配合使用,提供类型安全保障。 易于调试: 错误信息更直观,方便调试。 1.2 JSX 语法要点 单一根元素: JSX 必须包含在一个根元素中。
一、 JSX (JavaScript XML)
JSX 是一种 JavaScript 的语法扩展,允许你在 JavaScript 代码中编写类似 HTML 的结构。它并非真正的 HTML,而是会被 Babel 等工具编译成 JavaScript 代码,最终生成 React 组件。
1.1 JSX 的优势
声明式语法: JSX 使得 UI 结构更清晰,易于阅读和维护。
类型安全: JSX 可以与 TypeScript 等类型检查器配合使用,提供类型安全保障。
易于调试: 错误信息更直观,方便调试。
1.2 JSX 语法要点
单一根元素: JSX 必须包含在一个根元素中。
表达式: 可以使用花括号 {} 在 JSX 中嵌入 JavaScript 表达式。
属性: HTML 属性在 JSX 中通常采用驼峰命名法(camelCase),例如 className 代替 class。
注释: 在 JSX 中使用 /* ... */ 进行注释。
1.3 代码实践
import React from 'react'; function Greeting(props) { const name = props.name; return ( <div> <h1>Hello, {name}!</h1> <p>Welcome to React.</p> </div> ); } export default Greeting;
在这个例子中,我们使用 JSX 创建了一个 Greeting 组件,它接收一个 name prop,并将其显示在页面上。 花括号 {name} 用于嵌入 JavaScript 变量。
二、 组件 (Components)
组件是 React 应用的核心构建块。它们是独立、可重用的代码片段,负责渲染 UI 的特定部分。
2.1 组件类型
函数组件 (Functional Components): 简单的组件,接受 props 作为参数,并返回 JSX。
类组件 (Class Components): 拥有状态 (state) 和生命周期方法,可以处理更复杂的逻辑。
2.2 Props (Properties)
Props 是从父组件传递到子组件的数据。它们是只读的,子组件不能直接修改 props 的值。
2.3 State (状态)
State 是组件内部的数据,可以被组件自身修改。State 的改变会触发组件的重新渲染。
2.4 代码实践
函数组件 (Function Component):
import React from 'react'; function MyButton(props) { return ( <button onClick={props.onClick}> {props.label} </button> ); } export default MyButton;
类组件 (Class Component):
import React from 'react'; class Counter extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; this.handleClick = this.handleClick.bind(this); // 绑定 this } handleClick() { this.setState({ count: this.state.count + 1 }); } render() { return ( <div> <p>Count: {this.state.count}</p> <button onClick={this.handleClick}>Increment</button> </div> ); } } export default Counter;
2.5 组件生命周期 (Class Components only)
类组件拥有生命周期方法,允许你在组件的不同阶段执行代码,例如组件挂载、更新和卸载时。
constructor(): 组件创建时调用。
render(): 渲染组件的 UI。
componentDidMount(): 组件挂载到 DOM 后调用。
componentDidUpdate(): 组件更新后调用。
componentWillUnmount(): 组件卸载前调用。
2.6 使用 Hooks 的函数组件
自从 React 16.8 引入 Hooks 之后,函数组件也可以拥有 state 和生命周期方法,使得函数组件的功能更加强大。
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); // Similar to componentDidMount and componentDidUpdate: useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`; }, [count]); // Only re-run the effect if count changes return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
在这个例子中,useState Hook 用于管理 state,useEffect Hook 用于执行副作用操作 (例如更新文档标题),类似于 componentDidMount 和 componentDidUpdate。
三、 Props 和 State
Props 和 State 是 React 组件中管理数据的两种主要方式。
3.1 Props
用途: 从父组件向子组件传递数据。
特点: 只读,子组件不能直接修改 props 的值。
作用: 配置子组件的行为和外观。
3.2 State
用途: 管理组件自身的内部数据。
特点: 可变,组件可以修改 state 的值。
作用: 控制组件的渲染和交互。
3.3 Props vs State
| Feature | Props | State |
|---|---|---|
| Data Source | Parent Component | Component Itself |
| Mutability | Immutable (Read-Only) | Mutable (Can be modified) |
| Purpose | Configure Child Components | Manage Component's Internal Data |
3.4 代码实践
import React, { useState } from 'react'; function ParentComponent() { const [message, setMessage] = useState("Hello from parent!"); return ( <div> <ChildComponent message={message} /> <button onClick={() => setMessage("New message from parent!")}> Change Message </button> </div> ); } function ChildComponent(props) { return ( <p>{props.message}</p> ); } export default ParentComponent;
在这个例子中,ParentComponent 使用 useState Hook 管理 message 状态。它将 message 作为 prop 传递给 ChildComponent。 当点击按钮时,ParentComponent 更新 message 状态,导致 ChildComponent 重新渲染,显示新的消息。
四、 事件处理 (Event Handling)
React 使用合成事件系统来处理 DOM 事件。合成事件是浏览器原生事件的跨浏览器封装,具有更好的性能和一致性。
4.1 事件绑定
在 JSX 中,使用 onEventName 属性来绑定事件处理函数,例如 onClick、onChange 等。
4.2 事件对象
事件处理函数接收一个事件对象,该对象包含了有关事件的信息,例如目标元素、事件类型等。
4.3 代码实践
import React from 'react'; function MyButton() { function handleClick(event) { alert('Button clicked!'); console.log(event.target); // 打印触发事件的元素 } return ( <button onClick={handleClick}>Click me</button> ); } export default MyButton;
在这个例子中,handleClick 函数绑定到按钮的 onClick 事件。当按钮被点击时,handleClick 函数被调用,显示一个警告框并打印触发事件的元素到控制台。
五、 条件渲染 (Conditional Rendering)
React 允许你根据条件渲染不同的 UI 元素。
5.1 方式
if/else 语句: 在 JSX 中使用 JavaScript 的 if/else 语句。
三元运算符: 使用三元运算符 condition ? expression1 : expression2。
逻辑与运算符: 使用逻辑与运算符 condition && expression。
5.2 代码实践
import React, { useState } from 'react'; function Greeting() { const [isLoggedIn, setIsLoggedIn] = useState(false); return ( <div> {isLoggedIn ? ( <h1>Welcome back!</h1> ) : ( <h1>Please sign up.</h1> )} <button onClick={() => setIsLoggedIn(!isLoggedIn)}> {isLoggedIn ? 'Logout' : 'Login'} </button> </div> ); } export default Greeting;
在这个例子中,根据 isLoggedIn 状态,使用三元运算符渲染不同的标题。 点击按钮可以切换 isLoggedIn 状态,从而改变显示的标题。
六、 列表渲染 (List Rendering)
React 允许你使用 map() 方法渲染数组中的元素。
6.1 Key 属性
在渲染列表时,每个列表项都需要一个唯一的 key 属性。key 属性帮助 React 识别列表项的变化,从而更有效地更新 DOM。
6.2 代码实践
import React from 'react'; function NumberList(props) { const numbers = props.numbers; return ( <ul> {numbers.map((number) => <li key={number.toString()}> {number} </li> )} </ul> ); } const numbers = [1, 2, 3, 4, 5]; function App() { return ( <NumberList numbers={numbers} /> ); } export default App;
在这个例子中,map() 方法用于遍历 numbers 数组,并为每个数字创建一个 li 元素。 每个 li 元素都设置了一个唯一的 key 属性。
总结
本文深入探讨了 React 的核心概念,包括 JSX、组件、Props 和 State、事件处理、条件渲染和列表渲染。 通过代码实践和图表,希望能够帮助你更好地理解和应用这些概念,为构建复杂的 React 应用打下坚实的基础。 掌握这些核心概念是成为一名合格的 React 开发者的关键。