目录

React-常用-Hooks-详细解析

React 常用 Hooks 详细解析

React Hooks 是 React 16.8 引入的核心特性,允许在函数组件中使用状态、生命周期等特性,替代类组件的复杂逻辑。以下是常用 Hooks 的详细解析及最佳实践:


1.useState:状态管理

用途 :在函数组件中定义和更新局部状态。 示例 : import { useState } from ‘react’; const Counter = () => { const [count, setCount] = useState(0); // 初始值 0 return ( setCount(count + 1)}> Clicked {count} times ); }; 注意

  • 状态更新是异步的,连续调用 setCount(count + 1) 不会立即生效。
  • 若新状态依赖旧状态,应使用函数形式:setCount(prev => prev + 1)

2.useEffect:副作用处理

用途 :处理组件生命周期中的副作用(如数据请求、DOM 操作、订阅)。 示例 : import { useEffect, useState } from ‘react’; const DataFetcher = ({ url }) => { const [data, setData] = useState(null); useEffect(() => { const fetchData = async () => { const response = await fetch(url); setData(await response.json()); }; fetchData(); }, [url]); // 依赖项:url 变化时重新执行 return

{data ? data.name : ‘Loading…’}

; }; 注意

  • 依赖项数组
  • 空数组 []:仅在组件挂载时执行(类似 componentDidMount)。
  • 无数组:每次渲染后都执行(慎用)。
  • 包含变量:变量变化时重新执行。
  • 清理函数 :返回一个函数用于清理(如取消订阅、移除事件监听): useEffect(() => { const timer = setInterval(() => {}, 1000); return () => clearInterval(timer); // 组件卸载时清理 }, []);

3.useContext:跨组件数据传递

用途 :在组件树中共享数据,避免逐层传递 props。 示例 : import { createContext, useContext } from ‘react’; // 1. 创建 Context const ThemeContext = createContext(’light’); // 2. 提供数据 const App = () => (

); // 3. 消费数据 const Toolbar = () => { const theme = useContext(ThemeContext); return

Current theme: {theme}

; };


4.useReducer:复杂状态逻辑

用途 :类似 Redux 的状态管理,适合多状态关联或复杂更新逻辑。 示例 : import { useReducer } from ‘react’; const initialState = { count: 0 }; function reducer(state, action) { switch (action.type) { case ‘increment’: return { count: state.count + 1 }; case ‘decrement’: return { count: state.count - 1 }; default: throw new Error(); } } const Counter = () => { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} dispatch({ type: ‘increment’ })}>+ dispatch({ type: ‘decrement’ })}>- ); }; 适用场景 :状态更新涉及多个子值、依赖前一个状态、需要集中化管理。


5.useCallbackuseMemo:性能优化

useCallback:缓存函数

const handleClick = useCallback(() => { console.log(‘Clicked:’, count); }, [count]); // count 变化时重新创建函数

useMemo:缓存计算结果

const expensiveValue = useMemo(() => { return computeExpensiveValue(a, b); }, [a, b]); // a/b 变化时重新计算 最佳实践

  • 仅当子组件依赖这些值且用 React.memo 优化时使用。
  • 避免滥用,内存缓存本身也有开销。

6.useRef:持久化引用

用途

  • 访问 DOM 元素。
  • 保存可变值(类似类组件的实例变量),不会触发重新渲染。 示例 : const TextInput = () => { const inputRef = useRef(null); const focusInput = () => { inputRef.current.focus(); }; return ( <> Focus ); };

7.useLayoutEffect:同步副作用

用途 :与 useEffect 类似,但会在 DOM 更新后同步执行(在浏览器绘制前)。 适用场景 :需要直接操作 DOM 并确保用户看不到中间状态(如测量元素尺寸)。 示例 : useLayoutEffect(() => { const { width } = divRef.current.getBoundingClientRect(); setWidth(width); // 确保在渲染前获取最新尺寸 }, []);


8 自定义 Hook:逻辑复用

用途 :将组件逻辑封装为可复用的函数。 示例 :自定义 useFetch: const useFetch = (url) => { const [data, setData] = useState(null); useEffect(() => { const fetchData = async () => { const response = await fetch(url); setData(await response.json()); }; fetchData(); }, [url]); return data; }; // 使用 const MyComponent = () => { const data = useFetch(’/api/data’); return

{data}

; };


Hooks 使用规则

  1. 只在顶层调用 :不能在条件、循环或嵌套函数中使用 Hooks。
  2. 仅在 React 函数组件或自定义 Hook 中使用

总结

Hook核心用途典型场景
useState管理组件内部状态计数器、表单输入
useEffect处理副作用(数据请求、订阅)API 调用、事件监听
useContext跨组件共享数据主题、用户身份全局传递
useReducer复杂状态逻辑管理表单多字段、状态机
useCallback缓存函数,避免子组件无效渲染传递回调函数给优化过的子组件
useMemo缓存计算结果,减少重复计算复杂计算、优化渲染性能
useRef访问 DOM 或保存可变引用输入框聚焦、保存定时器 ID
useLayoutEffect同步 DOM 操作测量元素尺寸、强制同步更新
合理使用 Hooks 能显著提升代码可读性和可维护性,但需注意避免过度优化和滥用内存缓存。