小薛同学个人博客,XXTX的个人主页,acnb,ACNB,www.acnb.cn,个人主页,技术博客,编程学习,代码分享,全栈开发,前端开发,WordPress建站,Cloudflare CDN,JavaScript学习,Node.js教程,Python编程,网站建设,SEO优化,UI设计,用户体验,开发教程,IT技术,软件工程,计算机科学,互联网技术,网站开发,编程入门,高级编程,代码优化,项目实战,技术分享,学习资源,开发工具,开源项目,个人网站建设,博客搭建
2025-10-20
React

React Hooks深度解析

从基础使用到底层原理,全面掌握React Hooks

什么是React Hooks?

React Hooks是React 16.8引入的革命性特性,它允许函数组件拥有状态(state)和生命周期等特性,彻底改变了React开发方式。

注意: Hooks只能在函数组件的顶层调用,不能在循环、条件判断或嵌套函数中使用。

1. useState - 状态管理

useState是最基础也最常用的Hook,用于在函数组件中添加状态。

import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>点击次数: {count}</p> <button onClick={() => setCount(count + 1)}> 点击增加 </button> </div> ); }

1.1 函数式更新

当新状态依赖于旧状态时,应使用函数式更新:

setCount(prevCount => prevCount + 1);

2. useEffect - 副作用处理

useEffect用于处理副作用操作,如数据获取、订阅、手动DOM操作等。

useEffect(() => { // 组件挂载时执行 console.log('组件已挂载'); // 返回清理函数 return () => { console.log('组件即将卸载'); }; }, []); // 空依赖数组,只在挂载和卸载时执行

2.1 依赖数组

依赖数组控制useEffect的执行时机:

// 每次渲染都执行 useEffect(() => { /* ... */ }); // 只在挂载时执行 useEffect(() => { /* ... */ }, []); // 当count或name变化时执行 useEffect(() => { /* ... */ }, [count, name]);

3. useContext - 跨组件通信

useContext用于在组件树中传递数据,避免prop drilling。

// 创建Context const ThemeContext = React.createContext('light'); function App() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } function Toolbar() { const theme = useContext(ThemeContext); return <div>当前主题: {theme}</div>; }

4. useRef - 引用DOM或可变值

useRef返回一个可变的ref对象,其.current属性被初始化为传入的参数。

function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text" /> <button onClick={onButtonClick}>聚焦输入框</button> </> ); }

5. useReducer - 复杂状态管理

useReducer是useState的替代方案,适合处理复杂的状态逻辑。

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(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} <button onClick={() => dispatch({type: 'increment'})}>+</button> <button onClick={() => dispatch({type: 'decrement'})}>-</button> </> ); }

6. 自定义Hooks

自定义Hook可以将组件逻辑提取到可重用的函数中。

// 自定义Hook:获取窗口大小 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; } // 使用自定义Hook function MyComponent() { const size = useWindowSize(); return <div>窗口大小: {size.width}x{size.height}</div>; }

7. Hooks最佳实践

7.1 命名约定

  • 自定义Hook应以"use"开头
  • 状态变量使用描述性名称
  • Setter函数以"set"开头

7.2 性能优化

// 使用useMemo缓存计算结果 const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b] ); // 使用useCallback缓存函数 const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b] );

总结

React Hooks代表了React开发的未来方向,它让代码更加简洁、可重用和易于测试。掌握Hooks不仅能提高开发效率,还能写出更高质量的React代码。

记住以下几点:

  1. 只在React函数组件中使用Hooks
  2. 在组件顶层调用Hooks
  3. 正确处理依赖数组
  4. 合理使用性能优化Hooks