React Hooks 全解: 常用 Hooks 及使用场景详解

React Hooks 是 React 16.8 版本引入的一项重要特性,它极大地简化和优化了函数组件的开发过程。 React 中常用的 10 个 Hooks,包括 useState、useEffect、useContext、useReducer、useCallback、useMemo、useRef、useLayoutEffect、useImperativeHandle 和 useDebugValue。这些 Hooks 涵盖了状态管理、副作用处理、性能优化、DOM 操作等各个方面,为开发者提供了强大的工具,大幅提高了开发效率和代码质量。

在这里插入图片描述

无论您是 React 新手还是老手,全面而深入的 Hooks 知识,帮助您更好地掌握 React 函数组件的开发技巧。让我们一起探索 React Hooks 的强大功能,提升您的 React 开发水平。

  1. useState

    • 使用场景: 管理组件内部的状态
    • 示例代码:
      import { useState } from 'react';function Counter() {const [count, setCount] = useState(0);return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
      }
      
  2. useEffect

    • 使用场景: 处理组件生命周期,例如数据获取、订阅、手动更改 DOM 等
    • 示例代码:
      import { useState, useEffect } from 'react';function FetchData() {const [data, setData] = useState([]);useEffect(() => {async function fetchData() {const response = await fetch('/api/data');const data = await response.json();setData(data);}fetchData();}, []);return (<div><h1>Fetched Data</h1><ul>{data.map((item) => (<li key={item.id}>{item.name}</li>))}</ul></div>);
      }
      
  3. useContext

    • 使用场景: 跨组件传递数据,避免"prop drilling"
    • 示例代码:
      import { createContext, useContext } from 'react';const ThemeContext = createContext('light');function App() {return (<ThemeContext.Provider value="dark"><ThemedButton /></ThemeContext.Provider>);
      }function ThemedButton() {const theme = useContext(ThemeContext);return <button style={{ backgroundColor: theme === 'dark' ? 'black' : 'white' }}>Theme Button</button>;
      }
      
  4. useReducer

    • 使用场景: 管理复杂的状态逻辑
    • 示例代码:
      import { useReducer } from 'react';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, { count: 0 });return (<div><p>Count: {state.count}</p><button onClick={() => dispatch({ type: 'increment' })}>+</button><button onClick={() => dispatch({ type: 'decrement' })}>-</button></div>);
      }
      
  5. useCallback

    • 使用场景: 缓存函数引用,优化性能
    • 示例代码:
      import { useState, useCallback } from 'react';function Parent() {const [count, setCount] = useState(0);const handleClick = useCallback(() => {setCount(count + 1);}, [count]);return (<div><p>Count: {count}</p><ChildComponent onClick={handleClick} /></div>);
      }function ChildComponent({ onClick }) {console.log('ChildComponent rendered');return <button onClick={onClick}>Increment</button>;
      }
      
  6. useMemo

    • 使用场景: 缓存计算结果,优化性能
    • 示例代码:
      import { useState, useMemo } from 'react';function ExpensiveCalculation() {const [number, setNumber] = useState(0);const doubledNumber = useMemo(() => {return slowlyDoubleNumber(number);}, [number]);return (<div><input type="number" value={number} onChange={(e) => setNumber(parseInt(e.target.value))} /><p>Doubled number: {doubledNumber}</p></div>);
      }function slowlyDoubleNumber(n) {// 模拟一个耗时的计算let i = 0;while (i < 1000000000) i++;return n * 2;
      }
      
  7. useRef

    • 使用场景: 获取 DOM 元素引用,保存可变状态
    • 示例代码:
      import { useRef } from 'react';function FocusInput() {const inputRef = useRef(null);const handleClick = () => {inputRef.current.focus();};return (<div><input type="text" ref={inputRef} /><button onClick={handleClick}>Focus Input</button></div>);
      }
      
  8. useLayoutEffect

    • 使用场景: 处理 DOM 操作,需要同步执行
    • 示例代码:
      import { useLayoutEffect, useRef } from 'react';function MeasureElement() {const elementRef = useRef(null);useLayoutEffect(() => {const element = elementRef.current;console.log('Element width:', element.offsetWidth);}, []);return <div ref={elementRef}>This is the element to measure</div>;
      }
      
  9. useImperativeHandle

    • 使用场景: 暴露组件实例方法给父组件
    • 示例代码:
      import { forwardRef, useImperativeHandle, useRef } from 'react';const CustomInput = forwardRef((props, ref) => {const inputRef = useRef(null);useImperativeHandle(ref, () => ({focus: () => {inputRef.current.focus();}}));return <input type="text" ref={inputRef} />;
      });function App() {const inputRef = useRef(null);const handleClick = () => {inputRef.current.focus();};return (<div><CustomInput ref={inputRef} /><button onClick={handleClick}>Focus Input</button></div>);
      }
      
  10. useDebugValue

    • 使用场景: 为自定义 Hooks 提供调试标签
    • 示例代码:
      import { useState, useDebugValue } from 'react';function useCustomHook() {const [state, setState] = useState(0);useDebugValue(`Current state: ${state}`);// 自定义 Hook 的其他逻辑return [state, setState];
      }
      

这些是 React 中一些其他常用的 Hooks,它们可以帮助你进一步优化组件的逻辑和性能。每个 Hook 都有其特定的使用场景和使用方式,希望这个列表能为你提供一些参考和启发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/814272.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络——实现smtp和pop3邮件客户端

实验目的 运用各种编程语言实现基于 smtp 协议的 Email 客户端软件。 实验内容 1. 选择合适的编程语言编程实现基于 smtp 协议的 Email 客户端软件。 2. 安装 Email 服务器或选择已有的 Email 服务器&#xff0c;验证自己的 Email 客户端软件是否能进行正常的 Email 收发功…

GAMS104 现代游戏引擎 2

渲染的难点可以分为一下三部分&#xff1a;如何计算入射光线、如何考虑材质以及如何实现全局光照。 渲染的难点之一在于阴影&#xff0c;或者说是光的可见性。如何做出合适的阴影效果远比想象中要难得多&#xff0c;在实践中往往需要通过大量的技巧才能实现符合人认知的阴影效…

基于React Router6 TS实现路由守卫

定义路由表 import {BrowserRouter, Route, RouteObject, Routes,} from "react-router-dom"; import {Home, Login, NotFound} from "/views"; import {RouterGuard} from "/routers/router_guard.tsx"; import {ReactNode} from "react&…

js实现webp转png/jpg

网上保存的图片是webp类型的&#xff0c;但是我把它嵌入flac格式的音频里后导致网页中无法播放 wps要会员&#xff0c;真麻烦。 完整代码&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8">…

OpenHarmony实例应用:【常用组件和容器低代码】

介绍 本篇Codelab是基于ArkTS语言的低代码开发方式实现的一个简单实例。具体实现功能如下&#xff1a; 创建一个低代码工程。通过拖拽的方式实现任务列表和任务信息界面的界面布局。在UI编辑界面实现数据动态渲染和事件的绑定。 最终实现效果如下&#xff1a; 相关概念 低代…

leetcode刷题记录 day21

每日一题 找到冠军 I 一场比赛中共有 n 支队伍&#xff0c;按从 0 到 n - 1 编号。 给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 < i, j < n - 1 且 i ! j 的所有 i, j &#xff1a;如果 grid[i][j] 1&#xff0c;那么 i 队比 j 队 强 &a…

Tuxera Ntfs for mac 2023中文解锁版安装、密钥下载与激活教程 Tuxera激活码 tuxera破解

Tuxera Ntfs for mac2023是Mac中专用于读写外置存储的工具&#xff0c;具有强大的磁盘管理和修复功能&#xff0c;它在Mac上完全读写NTFS格式硬盘&#xff0c;快捷的访问、编辑、存储和传输文件。能够在 Mac 上读写 Windows NTFS 文件系统。Tuxera NTFS 实现在Mac OS X系统读写…

2024妈妈杯数学建模A 题思路分析-移动通信网络中 PCI 规划问题

# 1 赛题 A 题 移动通信网络中 PCI 规划问题 物理小区识别码(PCI)规划是移动通信网络中下行链路层上&#xff0c;对各覆盖 小区编号进行合理配置&#xff0c;以避免 PCI 冲突、 PCI 混淆以及 PCI 模 3 干扰等 现象。 PCI 规划对于减少物理层的小区间互相干扰(ICI)&#xff0c;增…

Java基础_19 IO流【重点】

1.File类会将此磁盘上面的文件或者文件夹抽象成为一个对象&#xff0c;可以拿对象调用方法来对咱们的文件或者文件夹操作(创建,删除&#xff0c;各种判断&#xff0c;查询)File类很多的方法createNewFilemkdirmkdirsdeleteisFileisDirectorygetNamegetPathgetParent2.递归算法【…

mysql搭建主从

mysql搭建主从: 1:拉取mysql镜像 docker pull mysql2:创建主从对应目录 3:建立一个简易的mysql docker run -it --name mytest -e MYSQL_ROOT_PASSWORD123 -d mysql4:进入这个简易的mysql;从中获取my.cnf文件 docker exec -it mytest bash5:从容器中将my.cnf拷贝到 /3306/c…

rspack 使用构建vue3脚手架

基于 Rust 的高性能 Web 构建工具。rspack 主要适配 webpack 生态&#xff0c;对于绝大多数 webpack 工具库都是支持的。 启动速度快&#xff1b;增量热更新快。兼容 webpack 生态&#xff1b;内置了 ts、jsx、css、css modules 等开箱即用。生产优化&#xff0c;tree shaking…

游戏内鼠标光标样式切换

参考自 通过程序设置鼠标的样式 - CodeBus 代码生成 .cur 文件附带详细注释-CSDN博客 读取当前目录里的鼠标文件 .cur // 程序名称&#xff1a;设置鼠标样式的范例 // 编译环境&#xff1a;Visual C 6.0~2022&#xff0c;EasyX_20220116 // #include <graphics.h> #in…

树莓派驱动开发--搭建环境篇(保姆级)

前言&#xff1a;树莓派的环境搭建关系到之后的驱动开发&#xff0c;故一个好的环境能让你顺手完成驱动开发&#xff01;我使用的是64位树莓派4b&#xff01;有显示屏的前提&#xff01;&#xff01;&#xff01;&#xff08;因为wifi连接太刁钻了&#xff09; 一、ubantu相关 …

java算法:反转数字

看算法描述&#xff1a; 1、给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 2、如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] &#xff0c;就返回 0。 3、假设环境不允许存储 64 位整数&#xff08;有符号或无符号&…

Linux如何安装kernel-debuginfo包以支持获取未压缩内核映像vmlinux?(yum | wget、rpm -ivh)

基础信息 本文以AnolisOS为例子&#xff0c;Centos和Ubuntu类似&#xff0c;核心都是安装kernel-debuginfo和kernel-debuginfo-common的rpm包 并且需要和内核版本子版本完全一致&#xff08;本质是使用同一份代码编译的&#xff09;假设系统安装的是8.6版本&#xff1a;比如ht…

【软件设计师】计算机软考下午题试题六,Java设计模式之简单工厂模式。

【软件设计师】计算机软考下午题试题六&#xff0c;Java设计模式之简单工厂模式。 代码如下&#xff1a; //简单工厂模式 public class SimpleFactory {public static void main(String[] args) {Product ProductAFactory.createProduct("A");ProductA.info();Produc…

C++11 数据结构2 线性表的链式存储,实现,测试

线性表的链式存储 --单链表 前面我们写的线性表的顺序存储(动态数组)的案例&#xff0c;最大的缺点是插入和删除时需要移动大量元素&#xff0c;这显然需要耗费时间&#xff0c;能不能想办法解决呢&#xff1f;链表。 链表为了表示每个数据元素与其直接后继元素之间的逻辑关系…

-bash:./app:没有那个文件或目录(已解决)

目录下有文件&#xff0c;并且权限也是够的&#xff0c;都是就是是没有。 解决方法&#xff1a; 进入/bin&#xff0c;执行命令 file bash 如上图&#xff0c;可以发现&#xff0c;bash是32-bit&#xff0c; 进入app所在目录&#xff0c;执行 file app 如上图&#xff0…

Java 基于微信小程序的校园失物招领小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

设计模式学习笔记 - 设计模式与范式 -行为型:16.解释器模式:如何设计实现一个自定义接口告警规则功能?

概述 上篇文章&#xff0c;我们学习了命令模式。本章&#xff0c;我们来学习解释器模式&#xff0c;它用来描述如何构建一个简单的 “语言” 解释器。比如命令模式&#xff0c;解释器模式更加小众&#xff0c;只在一些特定的领域内会被用到&#xff0c;比如编译器、规则引擎、…