跳转至

React 组件与 Hooks

组件基础

组件类型对比

方面 函数组件 类组件
语法 简单函数 ES6 类
状态管理 Hooks (useState, useReducer) this.state, this.setState
生命周期 useEffect 和其他钩子 生命周期方法
性能 更好的优化 需要手动优化
包大小 更小 更大
学习曲线 更容易 更陡峭
未来支持 ✅ 推荐 ⚠️ 遗留

受控与非受控组件

graph TD
    A["表单组件"] --> B["受控组件"]
    A --> C["非受控组件"]

    B --> B1["状态控制值"]
    B1 --> B2["onChange 更新状态"]
    B2 --> B3["可预测行为"]

    C --> C1["DOM 控制值"]
    C1 --> C2["Ref 读取值"]
    C2 --> C3["较少 React 控制"]

组件控制对比

特性 受控 非受控
数据源 React 状态 DOM 元素
值访问 直接从状态 通过 ref
验证 实时 提交时
性能 更多重新渲染 更少重新渲染
使用场景 动态表单 简单表单

Props 与 State 对比

方面 Props State
来源 父组件 组件自身
可变性 不可变 可变
目的 配置 内部数据
触发重新渲染 ✅ 是 ✅ 是
访问模式 props.propName state.stateName
更新方法 父组件更新 setState / useState

React Hooks

Hooks 概览

Hook 用途 返回值 常见用例
useState 管理组件状态 [state, setState] 表单输入,切换
useEffect 处理副作用 清理函数 API 调用,订阅
useContext 访问上下文值 上下文值 主题,用户数据
useReducer 复杂状态逻辑 [state, dispatch] 状态机
useMemo 缓存昂贵计算 缓存值 性能优化
useCallback 缓存回调函数 缓存函数 防止重新渲染
useRef 访问 DOM 或存储可变值 引用对象 DOM 操作

Hooks 分类

graph TD
    A["React Hooks"] --> B["状态管理"]
    A --> C["副作用"]
    A --> D["性能优化"]
    A --> E["上下文和引用"]

    B --> B1["useState"]
    B --> B2["useReducer"]

    C --> C1["useEffect"]
    C --> C2["useLayoutEffect"]

    D --> D1["useMemo"]
    D --> D2["useCallback"]

    E --> E1["useContext"]
    E --> E2["useRef"]

useState Hook 详解

不同上下文中的 setState 行为

上下文 行为 批处理 示例
React 生命周期方法 异步 ✅ 是 componentDidMount, componentDidUpdate
React 合成事件 异步 ✅ 是 onClick, onChange
setTimeout/setInterval 同步 ❌ 否 setTimeout(() => setState(), 0)
原生 DOM 事件 同步 ❌ 否 addEventListener('click', ...)
Promise 回调 同步 ❌ 否 .then(() => setState())

useState 执行流程

flowchart TD
    A["setState 调用"] --> B{"上下文检查"}

    B -->|"React 上下文"| C["异步"]
    B -->|"非 React 上下文"| D["同步"]

    C --> C1["批量更新"]
    C1 --> C2["单次重新渲染"]

    D --> D1["立即更新"]
    D1 --> D2["多次重新渲染"]

useEffect Hook 详解

useEffect 与生命周期方法对比

生命周期方法 useEffect 等价 依赖数组
componentDidMount useEffect(() => {}, []) 空数组
componentDidUpdate useEffect(() => {}) 无依赖数组
componentWillUnmount useEffect(() => { return () => {} }, []) 返回清理函数
componentDidMount + componentDidUpdate useEffect(() => {}, [dependency]) 特定依赖

useEffect 依赖模式

graph TD
    A["useEffect Hook"] --> B["依赖数组"]

    B --> B1["[] (空数组)"]
    B --> B2["[deps] (有依赖)"]
    B --> B3["无数组"]

    B1 --> B1a["运行一次"]
    B1a --> B1b["componentDidMount"]

    B2 --> B2a["依赖变化时运行"]
    B2a --> B2b["选择性更新"]

    B3 --> B3a["每次渲染都运行"]
    B3a --> B3b["componentDidUpdate"]

    A --> C["清理函数"]
    C --> C1["componentWillUnmount"]

useRequest (ahooks) 模式

核心特性

特性 描述 优势
统一状态 { loading, data, error } 一致的 API
自动执行 挂载时运行 更少样板代码
手动触发 run() 方法 按需请求
依赖刷新 依赖变化自动重试 响应式更新
内置优化 防抖、节流、轮询 更好的用户体验

请求流程图

sequenceDiagram
    participant C as Component
    participant U as useRequest
    participant A as API
    participant S as State

    Note over C,S: 初始挂载
    C->>U: useRequest(service, options)
    U->>S: loading: true
    U->>A: Execute request

    alt 成功
        A-->>U: Response data
        U->>S: { loading: false, data: response }
    else 错误
        A-->>U: Error
        U->>S: { loading: false, error: error }
    end

    Note over C,S: 手动触发
    C->>U: run(params)
    U->>S: loading: true
    U->>A: Execute with params