当前位置: 首页 > news >正文

JavaScript基础课程二十四、React Hooks 与实战

本课是 React 开发的核心进阶课程,聚焦 React Hooks 函数式编程体系。Hooks 彻底改变了 React 开发模式,让函数组件拥有状态与副作用能力,代码更简洁、逻辑更聚合。课程从基础 useState、useEffect、useRef 到性能优化 useMemo、useCallback,再到自定义 Hooks 封装,全面覆盖企业级 React 必备技能。通过单词实战案例,将状态管理、异步请求、DOM 操作、逻辑复用串联起来,帮助建立函数式编程思维。掌握本课内容,可独立开发标准 React 项目,轻松对接接口、处理副作用、优化性能,是 React 从入门到实战的关键一课。

一、课程学习目的

  1. 深入理解 React Hooks 的设计理念与核心作用,掌握函数式组件的状态与副作用管理。

  2. 熟练掌握常用 Hooks:useStateuseEffectuseRefuseMemouseCallback

  3. 学会自定义 Hooks 封装复用逻辑,提升代码模块化与可维护性。

  4. 掌握 React 性能优化基础手段,避免无效渲染。

  5. 能够使用 Hooks 完成完整实战项目,对接异步请求与业务逻辑。

  6. 建立 React 函数式编程思维,适配企业级 React 开发标准。

二、核心知识点讲解

1. React Hooks 概述

Hooks 是 React 16.8 推出的特性,让函数式组件拥有状态、生命周期、副作用等能力,彻底替代类组件。

Hooks 只能在函数组件顶层使用,不能在循环、条件、普通函数中调用。

优势:代码更简洁、逻辑更聚合、复用性更强、易于测试。

2. 基础必备 Hooks

  • useState:组件状态管理,修改状态自动触发视图更新。

  • useEffect:副作用处理(异步请求、定时器、DOM 操作)。

  • useRef:获取 DOM 元素、存储跨渲染数据。

  • useMemo:缓存计算结果,避免重复计算。

  • useCallback:缓存函数,避免子组件重复渲染。

3. 自定义 Hooks

自定义 Hooks 是以 use 开头的函数,内部可调用其他 Hooks,用于封装可复用逻辑(如请求、表单、定时器)。

作用:抽离公共逻辑、简化组件、提高可读性。

4. useEffect 依赖规则

  • 空数组[]:仅挂载、卸载时执行一次。

  • 带依赖[a,b]:依赖变化时执行。

  • 无依赖:每次渲染都执行。

  • 必须正确处理依赖,避免死循环。

5. React 状态更新规则

状态不可直接修改,必须通过set 函数返回新值。

对象/数组需使用展开语法创建新引用。

三、示例程序(带详细注释)

示例1:useState + useEffect 异步请求

import { useState, useEffect } from 'react' function WordList() { // 状态管理 const [wordList, setWordList] = useState([]) const [loading, setLoading] = useState(false) // 副作用:页面加载请求数据 useEffect(() => { async function getList() { setLoading(true) // 模拟请求 const res = await new Promise(r => setTimeout(() => r([ { en: 'book', cn: '书' }, { en: 'pen', cn: '笔' } ]), 1000)) setWordList(res) setLoading(false) } getList() }, []) // 空依赖 → 只执行一次 return ( <div> {loading && <p>加载中...</p>} {wordList.map((item, i) => ( <div key={i}>{item.en} - {item.cn}</div> ))} </div> ) }

示例2:useRef 获取 DOM

import { useRef } from 'react' function InputFocus() { const inputRef = useRef(null) const focus = () => { // 操作原生 DOM inputRef.current.focus() } return ( <div> <input ref={inputRef} /> <button onClick={focus}>聚焦</button> </div> ) }

示例3:自定义 Hooks(封装单词请求)

// hooks/useWord.js import { useState, useEffect } from 'react' // 自定义 Hook export function useWord() { const [wordList, setWordList] = useState([]) useEffect(() => { setTimeout(() => { setWordList([{ en: 'react', cn: 'React' }]) }, 800) }, []) return wordList } // 组件中使用 function App() { const wordList = useWord() return <div>{wordList.map(i => <div key={i.en}>{i.en}</div>)}</div> }

示例4:useMemo 缓存计算

import { useMemo } from 'react' function totalWord(wordList) { console.log('计算总数') return wordList.length } function App({ wordList }) { // 缓存结果,只有 wordList 变化才重新计算 const count = useMemo(() => totalWord(wordList), [wordList]) return <div>总数:{count}</div> }

四、掌握技巧与方法

  1. Hooks 必须在函数顶层调用,不能在 if / for / 普通函数里使用。

  2. useEffect 必须正确配置依赖,避免死循环或不执行。

  3. 状态不可变:不能直接 push / splice,必须返回新数组/对象。

  4. 公共逻辑抽离为自定义 Hooks,实现逻辑复用。

  5. useRef 可存储任何不需要触发渲染的数据。

  6. useMemo / useCallback 用于性能优化,不要过度使用。

  7. 异步请求必须放在 useEffect 或自定义 Hooks 中。

五、课后作业

基础作业

  1. 使用 useState + useEffect 实现单词列表异步加载,展示 loading 状态。

  2. 使用 useRef 获取输入框 DOM,实现按钮自动聚焦。

  3. 了解 useMemo 缓存计算结果的用法。

进阶作业

  1. 封装一个自定义 Hook,用于获取单词列表数据。

  2. 实现单词搜索功能,输入关键词实时过滤列表。

  3. 使用 useEffect 清理定时器/订阅,防止内存泄漏。

实战作业

  1. 开发 React 单词搜索系统:包含异步加载、搜索过滤、状态管理、自定义 Hooks,完整可运行。

上一课:前端框架实战(React 基础)实战作业代码

代码功能说明

本实战作业基于 Vite + React 开发单词管理系统,使用函数式组件与 JSX 语法,通过 useState 管理响应式状态(单词列表、输入框内容),实现添加、删除单词核心功能;利用 useEffect 在组件挂载时打印初始化日志;通过 Props 将单词数据传递给子组件展示,完成组件通信。页面包含输入框、操作按钮、列表渲染、空状态提示,符合 React 基础开发规范,完整覆盖 JSX、组件拆分、状态管理、事件处理、列表渲染等核心知识点,帮助快速掌握 React 基础开发流程。

注意事项

  1. 必须安装 Node.js 环境,使用 npm 安装依赖。

  2. React 使用 className 代替 class,style 需写成对象格式。

  3. 状态不可直接修改,必须使用 set 函数生成新值。

  4. 列表渲染 key 必须唯一,建议使用唯一 id,不推荐仅用 index。

  5. 组件名必须大写,文件后缀建议使用 .jsx。

  6. 运行命令:npm install → npm run dev。

  7. 禁止在 return 中直接修改状态,会导致无限渲染。

完整实战代码

项目结构

react-word-demo/ ├── index.html ├── package.json └── src/ ├── main.jsx ├── App.jsx ├── components/ │ └── WordItem.jsx └── index.css

src/main.jsx

import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <App /> </React.StrictMode> )

src/App.jsx

import { useState, useEffect } from 'react' import WordItem from './components/WordItem' function App() { const [wordList, setWordList] = useState([ { en: 'apple', cn: '苹果' }, { en: 'banana', cn: '香蕉' } ]) const [inputEn, setInputEn] = useState('') const [inputCn, setInputCn] = useState('') useEffect(() => { console.log('单词管理器已初始化') }, []) const addWord = () => { if (!inputEn || !inputCn) return setWordList([...wordList, { en: inputEn, cn: inputCn }]) setInputEn('') setInputCn('') } const delWord = (index) => { const newList = [...wordList] newList.splice(index, 1) setWordList(newList) } return ( <div className="app"> <h2>React 单词管理器</h2> <div className="input-box"> <input type="text" placeholder="英文" value={inputEn} onChange={(e) => setInputEn(e.target.value)} /> <input type="text" placeholder="中文" value={inputCn} onChange={(e) => setInputCn(e.target.value)} /> <button onClick={addWord}>添加</button> </div> <div className="list"> {wordList.length === 0 ? ( <p className="empty">暂无单词</p> ) : ( wordList.map((item, index) => ( <WordItem key={index} item={item} index={index} delWord={delWord} /> )) )} </div> </div> ) } export default App

src/components/WordItem.jsx

export default function WordItem({ item, index, delWord }) { return ( <div className="word-item"> <span>{item.en} — {item.cn}</span> <button onClick={() => delWord(index)}>删除</button> </div> ) }

src/index.css

.app { max-width: 600px; margin: 30px auto; padding: 20px; } .input-box { margin: 20px 0; } input { padding: 8px; margin-right: 6px; } button { padding: 8px 12px; background: #61dafb; border: none; cursor: pointer; border-radius: 4px; } .word-item { padding: 10px; background: #f5f5f5; margin: 6px 0; display: flex; justify-content: space-between; border-radius: 4px; } .empty { color: #999; padding: 20px 0; text-align: center; }

运行命令

npm install npm run dev

作业验收标准

  1. 项目可正常启动,无报错。

  2. 可添加、删除单词,视图实时更新。

  3. 空数据时展示空状态。

  4. 使用 useState、useEffect 正确。

  5. 组件拆分清晰,Props 传参正常。

  6. 代码规范、注释清晰、符合 React 基础标准。


http://www.jsqmd.com/news/537960/

相关文章:

  • OpenCV车位检测实战:从传统图像处理到YOLOv5的演进之路
  • 深入解析A2L文件:ECU标定与测量的关键结构
  • Deepin Boot Maker:开源启动盘制作工具的高效解决方案
  • ViGEmBus虚拟手柄驱动:5分钟快速上手完整教程
  • Open Interpreter一文详解:从安装到GUI控制完整步骤
  • VS Code+智谱AI+Cline 完整实战教程
  • 干涉测量、绝对测量仿真模拟与MATLAB的应用
  • 你的模型评估做对了吗?深入解读泰勒图里的R、RMSE和STD(以sklearn预测为例)
  • HunyuanVideo-Foley部署教程:RTX4090D镜像在Ubuntu22.04下的完整安装流程
  • 计算机组成原理实验:手把手教你用74LS181芯片搭建总线数据通路(含调试技巧)
  • Navicat试用期限制技术突破:完整解决方案与原理拆解
  • 别再死磕EKF了!用ESKF搞定无人机姿态估计,避开‘大数吃小数’的坑
  • Fastboot Enhance:一站式Android设备安全管理工具,让刷机操作化繁为简
  • 别再只看平均效果了!用R包grf的因果森林,手把手教你找出谁才是治疗的“天选之子”
  • ActiveReports for .NET 20.0 AIで进化する帐票开発环境
  • React 最核心 3 大底层原理:Fiber + Diff + 事件系统
  • ChatTTS离线包2024实战指南:从部署到性能优化的全流程解析
  • VRM-Addon-for-Blender完全掌握指南:从环境搭建到性能调优的7个关键技能
  • 用快马快速构建qoderwork官网概念验证原型,体验AI代码生成魔力
  • js获取浏览器指纹
  • Rockchip Android分区扩容避坑指南:除了super,你的cache和dtbo分区大小调对了吗?
  • 基于YOLO的x光安检危险物品检测 数据集介绍:类别为8类,包括:刀(knife)、剪刀(sc...
  • 《元创力》纪实录·外篇·烛影追光者,与不灭的星轨
  • Facebook BM账号如何投流?从入门到精通的完整指南
  • LVQ神经网络在人脸朝向识别中的应用实战
  • 抖音无水印下载器终极指南:3分钟快速保存高清视频
  • 【超详细教程:VMware Workstation Pro 中创建虚拟机(附配图指南)】
  • 伴热带生产厂家选购指南:5大核心标准帮你选对合作伙伴 - 速递信息
  • string(2)
  • Wan2.2-I2V-A14B快速上手:WebUI界面Prompt输入技巧与风格控制指南