React Hook 到底是干嘛的?一篇文章带你彻底搞懂 Hook 的作用和常见用法
一、什么是 React HookReact Hook本质上是一套让函数组件拥有更多能力的机制。你可以先记住一句最核心的话Hook 的作用就是让函数组件也能拥有状态、生命周期、副作用处理、逻辑复用等能力。通俗一点说以前 React 的函数组件只会干一件事根据数据把页面渲染出来。但是现实开发中一个组件往往不只是“显示页面”这么简单它还需要做很多事情比如记住用户输入的内容控制弹窗开关发送接口请求监听页面变化获取 DOM 元素复用一段公共逻辑而 Hook就是 React 提供给函数组件的一套“能力插件”。你可以把它理解成Hook 给函数组件装功能的工具箱。二、为什么会有 Hook要理解 Hook先得知道 React 以前是怎么写的。在 Hook 出现之前React 中如果你想让组件拥有状态、生命周期这些能力通常要使用类组件Class Component。比如一个最简单的计数器早期可能要这样写import React, { Component } from react; class Counter extends Component { constructor(props) { super(props); this.state { count: 0 }; } render() { return ( button onClick{() this.setState({ count: this.state.count 1 })} 点击了 {this.state.count} 次 /button ); } }这段代码没有错但很多初学者会觉得有点麻烦要写class要写constructor要写super要写this.state要写this.setStatethis指向有时候还容易出问题随着项目越来越复杂类组件还会涉及各种生命周期函数比如componentDidMountcomponentDidUpdatecomponentWillUnmount代码会越来越分散逻辑也越来越不容易维护。于是 React 官方推出了 Hook。它的目标非常明确让函数组件也能完成类组件的大部分能力而且写起来更简洁、更清晰、更容易复用逻辑。三、你可以怎么理解 Hook你可以把一个 React 组件想象成一个员工。一开始这个员工只会一件事把页面画出来。比如function Hello() { return h1Hello React/h1; }这就是一个最普通的函数组件。但如果你想让这个员工更能干一点比如记住一个数字页面加载后发请求监听窗口变化找到某个输入框并让它自动获取焦点那就需要给他配工具。而 Hook就是这些工具。比如useState给员工一个记事本让他能记住东西useEffect给员工一个任务清单让他在页面渲染后做额外事情useRef给员工一个抽屉可以放东西也能找到页面里的某个元素所以Hook 并不神秘。它就是让函数组件从“只能展示页面”升级成“能真正干活的组件”。四、最常见的 HookuseState在 React 中最常用的 Hook 之一就是useState。它的作用非常简单让组件记住一个值。比如我们写一个最基础的计数器import React, { useState } from react; function Counter() { const [count, setCount] useState(0); return ( button onClick{() setCount(count 1)} 点击了 {count} 次 /button ); } export default Counter;这段代码怎么理解最关键的是这句const [count, setCount] useState(0);你可以把它翻译成一句人话React帮我准备一个状态它的初始值是 0当前值叫 count修改它的方法叫 setCount。于是count是当前的状态值setCount是修改状态的方法useState(0)里的0是初始值点击按钮后执行setCount(count 1);React 就会更新状态然后重新渲染页面。为什么不能直接用普通变量很多初学者可能会写出这样的代码function Counter() { let count 0; return ( button onClick{() count} 点击了 {count} 次 /button ); }看起来你在修改count但页面并不会按预期更新。原因很简单普通变量的变化React 感知不到。React 只会对“状态”的变化做出响应而useState正是告诉 React这个值是组件状态请你帮我管理它。所以你可以这样记普通变量是你自己偷偷记React 不知道useState 是你正式告诉 React这个值要参与页面更新。五、第二个非常重要的 HookuseEffect除了状态组件还经常需要做一些“额外的事情”。比如页面加载后请求接口设置定时器监听滚动事件修改页面标题组件销毁时做清理这些事情并不是“渲染 UI”本身而是渲染之外的行为。React 把这类操作叫做副作用Effect。听起来有点专业其实你完全可以把它理解成组件渲染完后顺手做的事。这时候就要用到useEffect。先看一个例子import React, { useEffect } from react; function Demo() { useEffect(() { console.log(组件渲染完成了); }, []); return div你好React Hook/div; } export default Demo;这段代码的意思就是页面渲染出来以后执行一次里面的代码。[]是什么意思很多人第一次学useEffect最容易懵的地方就是第二个参数。useEffect(() { console.log(执行了); }, []);这里的[]叫做依赖数组。它决定这个副作用什么时候执行。1. 传空数组[]useEffect(() { console.log(只执行一次); }, []);表示组件第一次渲染完成后执行一次以后不再执行。这很像类组件里的componentDidMount。2. 不传第二个参数useEffect(() { console.log(每次渲染都执行); });表示组件每次渲染后都会执行。3. 传入依赖项useEffect(() { console.log(count 变化了); }, [count]);表示首次渲染会执行以后只有 count 变化时才执行。这个机制非常重要写业务代码时经常会用到。六、useEffect 最经典的应用请求接口比如页面加载后获取用户列表import React, { useEffect, useState } from react; function UserList() { const [users, setUsers] useState([]); useEffect(() { fetch(https://jsonplaceholder.typicode.com/users) .then((res) res.json()) .then((data) { setUsers(data); }); }, []); return ( div h2用户列表/h2 ul {users.map((user) ( li key{user.id}{user.name}/li ))} /ul /div ); } export default UserList;逻辑很清晰用useState([])准备一个用户列表状态用useEffect在组件第一次渲染后发请求请求回来后通过setUsers(data)更新状态页面自动重新渲染显示数据这就是 Hook 配合使用的典型场景。七、第三个常见 HookuseRef接下来再说一个很常用的 HookuseRef。它主要有两个用途获取 DOM 元素保存一个不会触发页面重新渲染的值先看第一个用途获取 DOM。比如页面加载后让输入框自动聚焦import React, { useEffect, useRef } from react; function InputFocus() { const inputRef useRef(null); useEffect(() { inputRef.current.focus(); }, []); return input ref{inputRef} placeholder请输入内容 /; } export default InputFocus;这里的逻辑是useRef(null)创建一个引用对象ref{inputRef}把这个引用绑定到 input 上页面渲染后通过inputRef.current拿到真实 DOM调用focus()让输入框自动获取焦点你可以把useRef理解成给页面元素贴了个标签方便以后找到它。useRef 的第二个用途useRef还可以用来保存一些值而且这些值变化时不会导致页面重新渲染。比如保存一个定时器 idimport React, { useEffect, useRef } from react; function TimerDemo() { const timerRef useRef(null); useEffect(() { timerRef.current setInterval(() { console.log(定时器执行中); }, 1000); return () { clearInterval(timerRef.current); }; }, []); return div定时器示例/div; } export default TimerDemo;这里的timerRef.current就像一个小盒子可以存放数据。和useState的区别是useState变化会触发重新渲染useRef变化不会触发重新渲染所以如果你只是想保存一个值但这个值不需要展示到页面上useRef很合适。八、React Hook 到底解决了什么问题这是很多面试中也会问到的问题。React Hook 主要解决了三个问题。1. 让函数组件拥有状态和副作用能力以前函数组件只能负责展示 UI复杂逻辑很多都要写在类组件里。Hook 出现后函数组件也能做这些事了开发体验更统一。2. 逻辑复用更方便以前如果你想复用一段组件逻辑常见方法有mixin高阶组件HOCRender Props这些方案不是不能用但随着项目变复杂代码嵌套会越来越深理解成本也越来越高。而 Hook 可以把一段逻辑直接提取成一个自定义 Hook。比如获取窗口宽度import React, { useEffect, useState } from react; function useWindowWidth() { const [width, setWidth] useState(window.innerWidth); useEffect(() { const handleResize () { setWidth(window.innerWidth); }; window.addEventListener(resize, handleResize); return () { window.removeEventListener(resize, handleResize); }; }, []); return width; } function Page() { const width useWindowWidth(); return div当前窗口宽度{width}/div; } export default Page;这里useWindowWidth()就是一个自定义 Hook。你会发现这种写法真的很舒服逻辑抽离清晰复用方便代码结构更自然3. 让组件代码更简洁、更易维护类组件中一个功能的相关代码可能分散在多个生命周期里。而用 Hook可以把“相关逻辑”写在一起。比如接口请求、事件绑定、清理逻辑都可以围绕一个功能集中组织这对维护大型项目非常友好。九、为什么 Hook 都要以 use 开头你肯定发现了React 官方提供的 Hook 都叫useStateuseEffectuseRefuseMemouseCallbackuseContext这是 React 的约定。凡是 Hook名字都要以use开头。包括你自己写的自定义 Hook也最好遵守这个规则function useWindowWidth() { // ... }为什么这么要求因为 React 和 ESLint 插件会根据use开头来识别这是不是一个 Hook。这样可以更好地检查代码是否符合 Hook 的使用规则。十、React Hook 的使用规则Hook 虽然很好用但它有两条非常重要的规则。1. 只能在函数组件或自定义 Hook 中调用你不能在普通的 JavaScript 函数中乱用 Hook。错误示例function test() { const [count, setCount] useState(0); }这是不允许的。正确示例function Counter() { const [count, setCount] useState(0); }或者function useCounter() { const [count, setCount] useState(0); return { count, setCount }; }2. 不要在条件语句、循环、嵌套函数中调用 Hook错误示例function Demo({ flag }) { if (flag) { const [count, setCount] useState(0); } return divDemo/div; }为什么不行因为 React 是按照 Hook 的调用顺序来管理状态的。如果你把 Hook 写在if里面那么某次渲染执行了某次渲染又没执行顺序就乱了React 就无法正确知道哪个 useState 对应哪个状态。所以一定要记住Hook 要写在组件顶层不能乱嵌套。十一、再来理解一下 Hook 的本质很多同学学 Hook 时最容易卡住的一点是函数组件不是每次渲染都会重新执行吗那它是怎么“记住状态”的这个问题问得特别好。确实函数组件每次渲染都会重新执行一遍。但是 React 内部会帮你“记住”每个 Hook 对应的数据。比如function Demo() { const [count, setCount] useState(0); const [name, setName] useState(Tom); return div{count} - {name}/div; }React 内部会根据 Hook 的调用顺序记录第一个useState对应count第二个useState对应name下次渲染时再按照同样顺序把数据取出来。这就是为什么 Hook 必须按固定顺序调用。所以从本质上说Hook 是 React 在函数组件中“挂接状态和副作用管理能力”的一种机制。十二、常见 Hook 快速总结下面把几个常见 Hook 用最简单的话概括一下。1. useState作用管理状态适合场景计数器输入框内容弹窗开关列表数据当前页码示例const [visible, setVisible] useState(false);2. useEffect作用处理副作用适合场景请求接口事件监听定时器手动操作 DOM修改页面标题示例useEffect(() { document.title 首页; }, []);3. useRef作用获取 DOM 或保存不会引起重渲染的值适合场景input 自动聚焦获取滚动容器保存定时器 id保存上一次的值示例const inputRef useRef(null);4. useMemo作用缓存计算结果适合场景复杂计算避免重复计算优化性能示例const total useMemo(() { return list.reduce((sum, item) sum item.price, 0); }, [list]);5. useCallback作用缓存函数适合场景把函数传给子组件时避免重复创建配合React.memo做性能优化示例const handleClick useCallback(() { console.log(点击了); }, []);6. useContext作用跨层级共享数据适合场景主题切换用户信息共享全局配置共享示例const theme useContext(ThemeContext);十三、初学者最容易犯的几个错误1. 把 useEffect 当成“任何逻辑都往里塞”有些初学者一学会useEffect就恨不得什么都丢进去。其实不是所有逻辑都要写进useEffect。原则是只有那些“渲染之后要做的事”才适合写进 useEffect。如果只是简单计算数据很多时候直接在组件里写就可以。2. 在 useEffect 里漏掉依赖比如useEffect(() { console.log(count); }, []);如果你的副作用里用到了count通常就应该把它写进依赖数组里useEffect(() { console.log(count); }, [count]);否则可能会出现数据不是最新值的问题。3. 把 useRef 和 useState 搞混记住一句非常关键的话需要更新页面的用 useState只是存值但不需要更新页面的用 useRef这个区别一定要分清。4. 在 if 中使用 Hook这个是典型错误。if (flag) { useEffect(() {}, []); }千万别这么写。Hook 一定要放在组件最外层。十四、一个完整小案例用 Hook 写一个待办事项列表下面我们用 Hook 写一个简单的 Todo List帮助你把useState和useEffect串起来理解。import React, { useEffect, useState } from react; function TodoApp() { const [inputValue, setInputValue] useState(); const [list, setList] useState([]); useEffect(() { const localData localStorage.getItem(todo-list); if (localData) { setList(JSON.parse(localData)); } }, []); useEffect(() { localStorage.setItem(todo-list, JSON.stringify(list)); }, [list]); const handleAdd () { if (!inputValue.trim()) return; setList([...list, inputValue]); setInputValue(); }; const handleDelete (index) { const newList list.filter((_, i) i ! index); setList(newList); }; return ( div h2Todo List/h2 input value{inputValue} onChange{(e) setInputValue(e.target.value)} placeholder请输入待办事项 / button onClick{handleAdd}添加/button ul {list.map((item, index) ( li key{index} {item} button onClick{() handleDelete(index)}删除/button /li ))} /ul /div ); } export default TodoApp;这个案例里用到了什么useState管理两个状态输入框内容inputValue待办列表list第一个useEffect页面第一次加载时从本地缓存读取数据。第二个useEffect每次list变化时把最新数据存到localStorage。这个例子特别适合初学者练手因为它同时涉及表单输入列表渲染状态更新副作用处理本地存储十五、React Hook 和类组件相比到底哪个好现在大多数新项目几乎都更倾向于函数组件 Hook原因很简单。Hook 的优点1. 代码更简洁不用写很多类组件模板代码。2. 逻辑更聚合一个功能相关的代码可以写在一起不容易分散。3. 更方便复用逻辑自定义 Hook 非常适合抽离通用能力。4. 更符合现在 React 的主流生态很多现代 React 项目、组件库、教程默认都基于 Hook。当然这并不是说类组件完全没用了。只是从开发趋势来看Hook 已经成为 React 的核心写法之一。十六、面试中怎么回答“React Hook 是什么”如果你面试时被问到这个问题可以参考下面这段回答React Hook 是 React 16.8 引入的一套新特性它允许我们在函数组件中使用状态、生命周期、副作用处理、引用、上下文等能力。Hook 的出现让函数组件不再只是无状态组件同时也让逻辑复用变得更加方便比如可以通过自定义 Hook 抽离公共逻辑。常见的 Hook 有 useState、useEffect、useRef、useMemo、useCallback、useContext 等。如果你想回答得更通俗一点也可以说Hook 就是 React 给函数组件提供的一套能力扩展机制让函数组件也能记数据、发请求、操作 DOM、复用逻辑。十七、总结学 React Hook最重要的不是一开始就把所有 Hook 全背下来而是先把最核心的三个搞懂useStateuseEffectuseRef你只要先彻底理解这三个React Hook 的大门基本就打开了。最后我们再用最简单的话总结一次useState是什么让组件记住数据。useEffect是什么让组件在渲染后执行额外操作。useRef是什么让组件获取 DOM或者保存不会触发重渲染的值。Hook 是什么Hook 就是让 React 函数组件拥有状态管理、副作用处理、DOM 操作和逻辑复用能力的一套机制。如果你之前一直觉得 Hook 很抽象那看到这里你至少应该已经明白Hook 并不是什么高深魔法它就是 React 给函数组件配的工具箱。十八、写在最后对于 React 初学者来说Hook 一开始确实会有点绕尤其是为什么要用useState为什么useEffect有依赖数组为什么 Hook 不能写在 if 里为什么函数组件每次重新执行却还能记住状态这些问题几乎每个 React 学习者都会遇到。但只要你多写几个小例子比如计数器输入框联动Todo List页面请求数据输入框自动聚焦Hook 很快就会从“抽象概念”变成“顺手工具”。建议你下一步重点练这几个方向useState控制表单和列表useEffect做接口请求和事件监听useRef获取 DOM 和保存临时值尝试自己写一个简单的自定义 Hook当你把这些练熟以后再去学useMemo、useCallback、useContext会轻松很多。

相关新闻

2026版基于springboot的儿童医院挂号管理系统

2026版基于springboot的儿童医院挂号管理系统

博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有实…

2026/7/9 7:37:30 阅读更多 →
《计算机组成原理》细致学:计算机的功能部件

《计算机组成原理》细致学:计算机的功能部件

从算盘的拨动到量子比特的跃迁,人类对计算的渴望从未停止。但现代计算机真正的“灵魂”诞生于 1945 年——冯诺依曼(John von Neumann)提出了“存储程序”的概念。这一天才的设想将计算机划分为五大基本功能部件,至今仍是我们手中…

2026/7/7 22:43:46 阅读更多 →
欧拉法:那个用切线“猜”未来的数学魔法

欧拉法:那个用切线“猜”未来的数学魔法

欧拉法:那个用切线“猜”未来的数学魔法 如果微积分是门预言术,欧拉法就是最朴素的占卜杖 前言:数学家也爱走捷径 想象一下,你正在追一部连续剧,但下周才更新。作为一个急不可耐的观众,你会怎么做?当然是根据已有的剧情,猜测接下来会发生什么! 300年前的欧拉老爷子也…

2026/7/7 11:16:53 阅读更多 →

最新新闻

2026汉中黄金回收白银回收铂金回收工商备案可查全城上门回收旧金老店联系方式推荐

2026汉中黄金回收白银回收铂金回收工商备案可查全城上门回收旧金老店联系方式推荐

2026汉中黄金白银铂金回收实测榜单|公安工商双备案无损测金无折旧费门店 汉中黄金回收哪家靠谱|工商公安双备案中检认证实体门店 汉中本地贵金属回收店铺遍地丛生,行业套路层出不穷,不少市民变现遭遇虚高报价、克扣损耗、未经同…

2026/7/9 14:16:01 阅读更多 →
DC-DC升压转换系统设计与MKV58微控制器应用

DC-DC升压转换系统设计与MKV58微控制器应用

1. 高电压DC-DC升压转换系统架构解析MKV58F1M0VLQ24微控制器与TPS61170的组合,构成了一个典型的数字控制型开关电源系统。MKV58作为主控芯片,通过PWM输出和ADC采样实现对TPS61170的闭环控制,这种架构在工业电源、医疗设备等对电压精度要求较高…

2026/7/9 14:14:01 阅读更多 →
PIC18F4553与CMT-8540S-SMT蜂鸣器的音频交互方案

PIC18F4553与CMT-8540S-SMT蜂鸣器的音频交互方案

1. 项目概述:为DIY项目添加声音交互的硬件方案在智能硬件和互动装置开发中,声音反馈是最直接的用户交互方式之一。PIC18F4553微控制器搭配CMT-8540S-SMT磁性蜂鸣器的组合,为各类电子项目提供了经济高效的音频解决方案。这个方案特别适合需要警…

2026/7/9 14:12:00 阅读更多 →
STM32F303VE驱动EPT-14A4005P的智能警报系统设计

STM32F303VE驱动EPT-14A4005P的智能警报系统设计

1. 项目概述:基于STM32F303VE与EPT-14A4005P的智能警报系统设计 警报系统在工业控制、安防监控和智能家居等领域扮演着关键角色。传统蜂鸣器在复杂环境中的穿透力往往不足,而专业级警报模块又存在成本过高的问题。本项目采用STM32F303VE微控制器驱动EPT-…

2026/7/9 14:12:00 阅读更多 →
如何快速解决Xcode版本不兼容问题:iOS开发者磁盘映像完整指南

如何快速解决Xcode版本不兼容问题:iOS开发者磁盘映像完整指南

如何快速解决Xcode版本不兼容问题:iOS开发者磁盘映像完整指南 【免费下载链接】Xcode_Developer_Disk_Images 项目地址: https://gitcode.com/gh_mirrors/xc/Xcode_Developer_Disk_Images 当你的iOS设备升级到新系统,但Xcode却提示缺少对应的开发…

2026/7/9 14:12:00 阅读更多 →
BilibiliDown:3步搞定B站视频批量下载与高品质音频提取的终极方案

BilibiliDown:3步搞定B站视频批量下载与高品质音频提取的终极方案

BilibiliDown:3步搞定B站视频批量下载与高品质音频提取的终极方案 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/g…

2026/7/9 14:09:54 阅读更多 →

日新闻

3大音乐平台逐字歌词完整解决方案:ESLyric-LyricsSource完全指南

3大音乐平台逐字歌词完整解决方案:ESLyric-LyricsSource完全指南

3大音乐平台逐字歌词完整解决方案:ESLyric-LyricsSource完全指南 【免费下载链接】ESLyric-LyricsSource Advanced lyrics source for ESLyric in foobar2000 项目地址: https://gitcode.com/gh_mirrors/es/ESLyric-LyricsSource 还在为Foobar2000找不到高质…

2026/7/9 0:01:04 阅读更多 →
ElegantBook封面定制揭秘:3个步骤打造专业级学术书籍

ElegantBook封面定制揭秘:3个步骤打造专业级学术书籍

ElegantBook封面定制揭秘:3个步骤打造专业级学术书籍 【免费下载链接】ElegantBook Elegant LaTeX Template for Books 项目地址: https://gitcode.com/gh_mirrors/el/ElegantBook 你是否曾经为学术书籍的封面设计而烦恼?想要一个既专业又美观的封…

2026/7/9 0:03:06 阅读更多 →
如何高效使用pyodbc:企业级数据库连接终极指南

如何高效使用pyodbc:企业级数据库连接终极指南

如何高效使用pyodbc:企业级数据库连接终极指南 【免费下载链接】pyodbc Python ODBC bridge 项目地址: https://gitcode.com/gh_mirrors/py/pyodbc 在当今数据驱动的商业环境中,企业级数据库连接已成为现代应用开发的核心需求。pyodbc作为一款强大…

2026/7/9 0:07:11 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/8 16:14:06 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/9 13:46:46 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/8 16:59:55 阅读更多 →

月新闻