Skip to Content

理解 React 的核心概念,将帮助开发者更好地使用 React 构建高效的用户界面。

基础概念

组件(Components)

就像乐高积木,每个组件都是独立的功能模块:

function Button() { return <button>点击我</button>; }

虚拟DOM(VDOM)

React 的”建筑图纸系统”,开发者的修改都会先在图纸上标记(生成新VDOM),施工队(协调机制)拿着新旧图纸对比后,只修改实际变化的部分:

// 设计草稿(旧VDOM) const oldBlueprint = { type: 'div', props: { children: 'Hello' } }; // 修订方案(新VDOM) const newBlueprint = { type: 'div', props: { children: [ 'Hello', { type: 'span', props: { children: ' World' } } ] } }; // 施工流程(Diffing算法) 1. 比对图纸类型变化(div → 保持) 2. 检查属性变化(无新增/删除) 3. 发现子节点变化: - 文本节点 'Hello' 保留 - 新增 <span> 节点
🏗️

React 的协调机制就像施工队长:

  1. 发现图纸变化后,标记需要修改的区域
  2. 重用可复用的建筑部件(DOM节点复用)
  3. 按最小修改量施工(DOM操作优化)

可视化比对流程:

JSX

让 HTML 住在 JavaScript 里的魔法语法:

const element = <h1 className="title">你好 React</h1>;

组件渲染

列表渲染与 Keys

给列表元素配”身份证号码”,避免更新混乱:

function TodoList({ todos }) { return ( <ul> {todos.map((todo) => ( <li key={todo.id}> {/* 唯一标识符 */} {todo.text} <button onClick={() => handleDelete(todo.id)}>删除</button> </li> ))} </ul> ); } // 错误示例:使用数组索引作为 key {todos.map((todo, index) => ( <li key={index}>...</li> {/* 可能导致渲染问题 */} ))}
💡

Key 应该来自数据的唯一标识,推荐使用 ID 而非索引

协调机制 (Reconciliation)

React 的”版本对比系统”,像快递分拣员比较新旧包裹:

// 旧包裹 <ul> <li>苹果</li> <li>香蕉</li> </ul> // 新包裹 <ul> <li>橙子</li> <li>苹果</li> <li>香蕉</li> </ul> // React 会智能地只插入橙子

组件交互

Refs

组件的”遥控器”,直接操控 DOM 元素:

// 函数组件用法 function TextInput() { const inputRef = useRef(null); const focusInput = () => inputRef.current?.focus(); return ( <> <input ref={inputRef} /> <button onClick={focusInput}>聚焦输入框</button> </> ); } // 类组件用法 class AutoFocusInput extends React.Component { constructor(props) { super(props); this.inputRef = React.createRef(); } componentDidMount() { this.inputRef.current.focus(); } render() { return <input ref={this.inputRef} />; } }
⚠️

Ref 应作为 DOM 操作的逃生舱,优先使用声明式数据流

Props

组件之间的传纸条:

function Welcome(props) { return <h1>你好, {props.name}</h1>; }

State

组件的便签纸(记忆功能):

function Counter() { const [count, setCount] = useState(0); return <button onClick={() => setCount(count+1)}>点击 {count}</button>; }

高级特性

错误边界 (Error Boundary)

组件的”安全气囊”,防止局部错误导致整个应用崩溃:

class ErrorBoundary extends React.Component { state = { hasError: false } static getDerivedStateFromError(error) { return { hasError: true } } render() { return this.state.hasError ? <h1>零件故障,正在检修</h1> : this.props.children } } // 使用方式 <ErrorBoundary> <BuggyComponent /> </ErrorBoundary>

自定义 Hooks

打造专属的”多功能工具包”:

function useWindowSize() { const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight }) useEffect(() => { const handleResize = () => setSize({ width: window.innerWidth, height: window.innerHeight }) window.addEventListener('resize', handleResize) return () => window.removeEventListener('resize', handleResize) }, []) return size } // 在组件中使用 const { width } = useWindowSize()

Suspense

组件的”加载中提示牌”,优雅处理异步操作:

const LazyComponent = React.lazy(() => import('./HeavyComponent')); function App() { return ( <React.Suspense fallback={<div>正在加载...</div>}> <LazyComponent /> </React.Suspense> ); } // 配合错误边界使用 <ErrorBoundary> <Suspense fallback={<Loading />}> <AsyncContent /> </Suspense> </ErrorBoundary>

React 18 新特性

并发模式 (Concurrent Mode)

组件的”交通信号灯系统”,优先处理紧急更新:

// 使用并发渲染 const root = createRoot(document.getElementById('root')) root.render( <ConcurrentMode> <App /> </ConcurrentMode> )

自动批处理

状态更新的”快递合并发货”:

function handleClick() { setName('李雷') // 不会立即渲染 setAge(18) // 不会立即渲染 // 所有更新会批量处理 }

Hooks

组件的瑞士军刀:

useEffect(() => { document.title = `点击了 ${count} 次`; }, [count]);

Context

组件树的广播系统:

const ThemeContext = createContext('light'); function App() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); }
⚠️

实际开发中建议搭配 TypeScript 使用以获得更好的类型提示

🚀

React 18 的并发特性需要配合 createRoot 使用,可显著提升复杂应用的交互流畅度

Last updated on