React 如何自定义 Hooks
自定义 Hooks
React 内部自带了很多 Hooks 例如 useState、useEffect 等等,那么我们为什么还要自定义 Hooks?使用 Hooks 的好处之一就是重用,可以将代码从组件中抽离出来定义为 Hooks,而不用每个组件中重复去写相同的代码。首先是维护方便,更重要的是封装,Hooks 将业务逻辑进行了封装,只要返回值不变,任何改动对组件都是透明的。
Hooks的设计中,将状态保存在Filber节点上,组件是无状态的,在我们的自定义 Hooks 中通过 useState 访问数据,通过 useEfftect 做副作用逻辑处理。例如,实现一个获取在线人数的 Hooks:
import { useState, useEffect } from 'react';const useOnlineUsers = (apiUrl) => {const [onlineUsers, setOnlineUsers] = useState(0);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);useEffect(() => {const fetchOnlineUsers = async () => {try {setLoading(true);const response = await fetch(apiUrl);if (!response.ok) {throw new Error('网络响应不正常');}const data = await response.json();setOnlineUsers(data.totalOnlineUsers);} catch (error) {setError(error.message);} finally {setLoading(false);}};fetchOnlineUsers();// 可选:设置轮询来定期更新在线用户数量const intervalId = setInterval(fetchOnlineUsers, 10000); // 例如,每10秒更新一次// 清理函数来清除 intervalreturn () => clearInterval(intervalId);}, [apiUrl]);return { onlineUsers, loading, error };
};export default useOnlineUsers;
Hooks中通过 useEffect 从后台获取用户数,在需要显示的组件中进行引用:
import React from 'react';
import useOnlineUsers from './useOnlineUsers'; // 根据你的项目结构调整路径const OnlineUsersComponent = () => {const apiUrl = 'https://api.example.com/online-users'; // 替换为你的实际 API URLconst { onlineUsers, loading, error } = useOnlineUsers(apiUrl);if (loading) {return <div>加载中...</div>;}if (error) {return <div>错误: {error}</div>;}return (<div><h1>在线用户数: {onlineUsers}</h1></div>);
};export default OnlineUsersComponent;
自定义 Hooks 的注意事项
- 命名规范
自定义 hooks 的名称应该以 “use” 开头,这不仅是为了遵循 React 的惯例,还能使其在代码中一目了然地被识别为 hooks。
const useOnlineUsers = () => {// hook implementation
};
- 使用依赖项数组优化性能
在 useEffect 或其他 hooks 中使用依赖项数组来避免不必要的重复执行。
useEffect(() => {// effect logic
}, [dependency1, dependency2]); // 只有当 dependency1 或 dependency2 发生变化时,effect 才会重新执行
- 返回需要的所有值
从自定义 hook 返回所有需要的状态和函数,而不仅仅是一个值。这可以让使用 hook 的组件更灵活,就像 useState 一样。
const useCounter = (initialValue = 0) => {const [count, setCount] = useState(initialValue);const increment = () => setCount(count + 1);const decrement = () => setCount(count - 1);return { count, increment, decrement };
};// 在组件中使用
const CounterComponent = () => {const { count, increment, decrement } = useCounter(10);return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button><button onClick={decrement}>Decrement</button></div>);
};
总结
Hooks 提供了非常优雅的设计方式,通过自定义 Hooks 来提升代码的复用与封装,在日常开发中,也不要过度的使用自定义 Hooks,对于一些简单不需要封装的业务逻辑,则无需定义为 Hooks。
相关文章:
React 如何自定义 Hooks
自定义 Hooks React 内部自带了很多 Hooks 例如 useState、useEffect 等等,那么我们为什么还要自定义 Hooks?使用 Hooks 的好处之一就是重用,可以将代码从组件中抽离出来定义为 Hooks,而不用每个组件中重复去写相同的代码。首先是…...
智能家居完结 -- 整体设计
系统框图 前情提要: 智能家居1 -- 实现语音模块-CSDN博客 智能家居2 -- 实现网络控制模块-CSDN博客 智能家居3 - 实现烟雾报警模块-CSDN博客 智能家居4 -- 添加接收消息的初步处理-CSDN博客 智能家居5 - 实现处理线程-CSDN博客 智能家居6 -- 配置 ini文件优化设备添加-CS…...
双指针用法练习题(2024/5/26)
1三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元…...
Ansible02-Ansible Modules模块详解
目录 写在前面4. Ansible Modules 模块4.1 Ansible常用模块4.1.1 Command模块4.1.2 shell模块4.1.3 scrpit模块4.1.4 file模块4.1.5 copy模块4.1.6 lineinfile模块4.1.7 systemd模块4.1.8 yum模块4.1.9 get_url模块4.1.10 yum_repository模块4.1.11 user模块4.1.12 group模块4.…...
【Python特征工程系列】一文教你使用PCA进行特征分析与降维(案例+源码)
这是我的第287篇原创文章。 一、引言 主成分分析(Principal Component Analysis, PCA)是一种常用的降维技术,它通过线性变换将原始特征转换为一组线性不相关的新特征,称为主成分,以便更好地表达数据的方差。 在特征重要…...
【Linux】Ubuntu系统挂载NAS文件夹
测试系统:Ubuntu24.02 1. 安装必要的软件包 sudo apt update sudo apt install cifs-utils 2. 创建挂载点 sudo mkdir -p /mnt/nas 3. 获取当前用户的 UID 和 GID id -u id -g 4. 挂载:设置用户名/密码/nas地址 sudo mount -t cifs -o username,…...
如何用ai打一场酣畅淋漓的数学建模比赛? 给考研加加分!
文章目录 数学建模比赛1. 数学建模是什么?2. 数学建模分工合作2.1 第一:组队和分工合作2.2 第二:充分的准备2.3 第三:比赛中写论文过程 3. 数学建模基本过程4. 2023全年数学建模竞赛时间轴5. 数学建模-资料大全6. 数学建模实战 数…...
深入浅出MySQL事务实现底层原理
重要概念 事务的ACID 原子性(Atomicity):即不可分割性,事务中的操作要么全不做,要么全做一致性(Consistency):一个事务在执行前后,数据库都必须处于正确的状态…...
SVM兵王问题
1.流程 前面六个就是棋子的位置,draw就是逼和,后面的数字six就代表,白棋最少用六步就能将死对方。然后呢,可以看一下最后一个有几种情况: 2.交叉测试 leave one out: 留一个样本作测试集,其余…...
yolov5_obb
yolov5_obb: 旋转目标检测从数据制作到终端部署全流程教学...
NextJs 初级篇 - 安装 | 路由 | 中间件
NextJs 初级篇 - 安装 | 路由 | 中间件 一. NextJs 的安装二. 路由2.1 路由和页面的定义2.2 布局的定义和使用2.3 模板的定义和使用① 模板 VS 布局② 什么是 use client 2.4 路由跳转的方式2.5 动态路由2.6 路由处理程序① GET 请求的默认缓存机制② 控制缓存或者退出缓存的手…...
变分自动编码器(VAE)深入理解与总结
本文导航 0 引言1 起源1.1 自编码器的任务定义1.2 自编码器存在的问题1.3 VAE的核心思路 2 VAE的建模过程2.1 VAE的任务定义2.2 真实分布 ϕ \phi ϕ是什么,为什么要逼近这个分布的参数,如何做?2.3 “重参数化(Reparameterization…...
Leetcode 剑指 Offer II 079.子集
题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一个整数数组 nums ,数组中的元素 互不相同 。返…...
Linux基础命令常见问题解决方案
Linux 基础命令常见问题解决方案 在Linux的日常使用中,用户经常会遇到各种各样的问题。本文旨在提供一个关于Linux基础命令的常见问题及其解决方案的全面指南。我们将覆盖30种不同的错误场景,并给出具体的解决步骤和示例,帮助初学者快速定位…...
LINQ(五) ——使用LINQ进行匿名对象初始化
总目录 C# 语法总目录 上一篇:LINQ(四) ——使用LINQ进行对象类型初始化 LINQ 五 ——使用LINQ进行匿名对象初始化 6.2 匿名类型 6.2 匿名类型 可以不用声明定义一个对象,直接使用new,然后直接赋值即可 string[] names { "Tom",…...
1小时从0开始搭建自己的直播平台(详细步骤)
本文讲述了如何从0开始,利用腾讯云的平台,快速搭建一个直播平台的过程。 文章目录 效果图详细步骤准备工作第一步:添加域名并检验cname配置1.先填加一个推流域名2. 点击完下一步,得到一个cname地址3. 将cname地址,配置…...
Python打包篇-exe
文章目录 pyinstallerauto-py-to-exe pyinstaller 命令行工具,语法自行查看官方help pip install pyinstallerauto-py-to-exe 基于pyinstaller的一款GUI工具,会自行打包py文件中依赖的库 pip install auto-py-to-exe auto-py-to-exe.exe //运行即可...
游戏找不到d3dcompiler_43.dll怎么办,教你5种可靠的修复方法
在电脑使用过程中,我们经常会遇到一些错误提示,其中之一就是“找不到d3dcompiler43.dll”。这个问题通常出现在游戏或者图形处理软件中,它会导致程序无法正常运行。为了解决这个问题,我经过多次尝试和总结,找到了以下五…...
如何使用多种算法解决LeetCode第135题——分发糖果问题
❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容,和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣! 推荐:数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航: LeetCode解锁100…...
泰拉瑞亚从零开始的开服教程
前言 本教程将讲诉使用Linux系统搭建泰拉瑞亚服务器(因为网上已经有很完善的windows开服教程了),使用的Linux发行版是Debian11,服务端使用的程序是TShock,游戏版本是1.4.4.9 所需要准备的 一台服务器(本教程使用的是…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
