弄懂自定义 Hooks 不难,改变开发认知有点不习惯

news2024/11/27 16:50:39

前言

我之前总结逻辑重用的时候,就一直在思考一个问题。

对于逻辑复用,render props 和 高阶组件都可以实现,同样官方说 Hooks 也可以实现,且还是在不增加额外的组件的情况下。

但是我在项目代码中,没有找到自定义 Hooks 的身影,自己也很少写。所以是为什么呢?

遇到问题表示查漏补缺的机会来了。

遇到技术点先问几个为什么

偶尔我会先问自己几个为什么,然后去寻找答案。带着明确的目标,不容易漏掉重要的讯息。

1.什么是自定义 Hooks?很难实现吗?
2.自定义 Hooks 和普通函数有什么区别?
3.如何创建一个自定义 Hook?
4.为什么需要自定义 Hooks?哪些场景会用到?
5.为什么我好像平时用不到?

自定义 Hooks 很难吗?

自定义 hooks可以看做是 React Hooks 的之外的自由延伸。本质上还是 JavaScript 函数。主要用途是实现逻辑重用。

React Hooks、函数、逻辑重用,根据这些关键字观察,实现自定义 Hooks 应该不是很难。

自定义 Hooks 和普通函数有什么区别?

看了关于自定义 Hooks 的介绍,我冒出来了第二个小问号:

这跟普通的逻辑复用函数有什么区别呢?

于是,我认真阅读了React的官方文档,发现主要有两点区分:

  • 名字应该始终以 use 开头。
  • 在自定义 Hook 中调用其他 Hook。

如何创建一个自定义 Hook?

因为Hook 本质是 JavaScript 函数,所以创建自定义 Hook其实就是声明一个名字以 use 开头的函数。

useDateRange

这个自定义 Hook 的过程算是意外惊喜,我在看完官方的例子之后,一直在想我实际开发中有哪些部分可以通过自定义 Hook实现逻辑的重用。

然后意外发现了项目中存在的可优化空间,后续会陆续产出优化的经验。

这里我先以项目中常出现的日期选择器为例,演示一下创建自定义 Hook 的全过程。

自定义 Hook 介绍

当前的需求如下:

  • 日期选择器,需要设置可选日期范围,超出1天~10天的范围不可选择。
  • 选择某个日期之后,需要计算跟当天日期相差的天数,并回显到页面上。

注:日期选择器使用的 antd 提供的组件,所有的参数均可以在官网查看。

UI 效果

可选日期效果

相差天数回显

可复用逻辑提取

可复用的逻辑主要包括三个部分:日期选择器的可选限制、时间发生变化的回调函数、相差天数变量。

日期选择器的可选限制

moment.js 的 add 方法可以计算指定时间之后(或之前)的某个时间。结合 startOf 方法和 endOf 方法使用,可以确定可选范围的起始日期。

时间发生变化的回调函数

当选定日期的时候,回调函数会返回选中的日期。

相差天数

通过时间回调函数拿到当前选择的日期,使用 moment.js 的 diff 方法,与今天的日期做比较。diff 方法的第二个参数决定差值的度量单位,day表示天数。

/**
 * @description 时间选择器的限制和相差天数
 */
import React, { useState, useCallback, useMemo } from 'react';
import moment from 'moment';

const useDateRange = () => {// 相差天数let [dayDiff, setDayDiff] = useState(0);/** * 可选时间范围 1~10 */const disabledDate = useCallback(current => {const startTimer = moment().add(+1, 'days').startOf('day');const endTimer = moment().add(+10, 'days').endOf('day');return current && (current < startTimer || current > endTimer);}, []);/** * 时间选择器选择操作 获取相差天数 */const dateChange = useCallback(dates => {let nowDate = new Date();let startData = moment(nowDate).format('YYYY-MM-DD');let endData = moment(dates).format('YYYY-MM-DD');dayDiff = moment(endData).diff(moment(startData), 'day');setDayDiff(dayDiff);}, []);return { dayDiff, disabledDate, dateChange };
};
export default useDateRange; 

使用 useDateRange

引入自定义的 useDateRange 这个 Hook,就可以拿到传入的参数了。

/**
 * @description 日期选择页
 */
import React from 'react';
import { DatePicker } from 'antd';
import useDateRange from './hooks/useDateRange';

const ChangeDatePage = () => {// 使用自定义 Hookconst { disabledDate, dateChange, dayDiff } = useDateRange();return (<div><DatePicker disabledDate={disabledDate} onChange={dateChange} /><div className="mt20">选择的日期与今天相差: {dayDiff} 天</div></div>);
};

export default ChangeDatePage; 

自定义 Hooks 的优势和使用场景

等了解了它的优势,基本也就能联想到有哪些使用场景。

优势

自定义 Hooks 主要有两点优势:

  • 逻辑复用
  • 复杂代码分离

使用场景

通过对自定义 Hooks 了解和使用,可以归纳的使用场景主要包括三个大类:

封装可复用的逻辑、监听数据的状态、拆分复杂的逻辑

基于这三类场景,可应用的地方应该不少。未来一段时间,我准备改造一下我们的项目代码,这下事情开始有趣了。

为什么我好像平时用不到?

为何纠结用不到这件事?

先简单说一下最近为什么一直纠结用不到这件事。因为身处「业务驱动技术」的技术科技公司,业务迭代是很迅速的,想在快节奏的开发中,整个前端团队保持一个较高水平的开发水平,不是很容易。

想在逻辑复用上下一些功夫,提升开发效率,团队成员可以腾出一些时间进行技术升级。

开发认知

自定义 Hooks 和普通函数的界限是可变的,加上平时开发的命名不太习惯用 use 开头。

所以用到的少,并不是因为自定义 Hooks 的开发难度或者开发者技术水平,而是改变这个开发认知有点不习惯。

但是个人认为改变是有帮助的。

  • 已知自定义 Hooks 主要用途是进行逻辑复用,那么从 use 开头的函数名,使用者不难联想到该函数方法是不是封装了某个公共的逻辑。
  • 其实除了逻辑复用,复杂逻辑的拆分,也可以考虑用自定义 Hooks 实现。

今日总结

今天除了清楚自定义 Hooks的相关知识点、如何创建以及使用场景。还帮助我衍生了新的开发思路,让我对原以为无法进行逻辑复用的功能,有了新的想法。

后面如果有了更好的开发思路,会持续输出文章分享出来。

彩蛋

今天的彩蛋,讲个之前困扰过我问题以及后来我总结出来的经验。

现阶段一直在写业务代码,感觉技术上没有得到什么提升?

我之前也被这个问题困扰过。后来,我从身边很多优秀的思维中,总结了一些经验,也就不再纠结这个问题。

误区在哪?

技术和业务的关系,不是对立面,而是相辅相成、相得益彰的。尤其现在大多数是业务驱动型公司。已知「技术可推动业务的发展」,同样的业务日趋繁复,倒逼技术的更迭。

日复一日重复的功能?

遇到这个困惑时,不排除一种可能,受思维定式的影响,重复之前的实现方式。

但是功能本身未必不能用更好的方式去实现。

举个例子,搜索项常见于表格页面,因为每个页面的搜索项都不太一样,很长一段时间,都被散落在各个页面中。其实搜索项的类型基本就那几种,于是有同事封装了一个公共组件,只需要传入包含搜索项基础信息的配置数组变量即可。

以前散落在每个页面的搜索项,如果再加上事件的处理,冗余代码量会更多。

<div><label>城市:</label><Input placeholder='请输入城市' />
</div>
<div><label>分类:</label><Select placeholder='请选择'><Select.Option key='1'>分类1</Select.Option><Select.Option key='2'>分类2</Select.Option></Select>
</div> 

后来封装成公共组件之后,代码简洁了很多,且大部分逻辑处理在组件中,使用时开发者并不用关心这些。

const fields = [{label: '城市',fieldtype: 'input',},{label: '分类',fieldtype: 'select',option: [{key: 1,value: '分类1'},{key: 2,value: '分类2'},]},
]
<Search fields={fields} /> 

工作中找不到项目练手?

我把日常的经验总结为:主动出击和没有条件创造条件。

  • 如果有一定的能力,可以申请功能立项或者参与一些工程化建设项目。自己主动把握机会。
  • 追随开拓者,自己创造条件。从模仿优秀的开源的项目到开发属于自己独立思维的项目过度,也是一个不错的选择。

总结时刻

三个问题和三个解答,解铃还须系铃人,心结还需自己解。

最后

整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享

部分文档展示:



文章篇幅有限,后面的内容就不一一展示了

有需要的小伙伴,可以点下方卡片免费领取

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

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

相关文章

python | 第二章考试题和练习题

一、考试题 1、turtle八边形绘制 问题描述&#xff1a; 使用turtle库&#xff0c;绘制一个八边形。 参考代码&#xff1a; import turtle as t t.pensize(2) for i in range(8):t.fd(100)t.left(45) 2、turtle八角图形绘制 问题描述&#xff1a; 使用turtle库&#xff0c;…

SaleSmartly(ss客服)带你了解:缩短B2B销售周期的秘诀

缩短B2B销售周期的秘诀&#xff1a;即时聊天 关键词&#xff1a;B2B 销售&#xff1b;即时沟通&#xff1b;SaleSmartly&#xff08;ss客服&#xff09; 在B2B销售中&#xff0c;时间就是一切。在某些情况下&#xff0c;买家正在积极寻找即时解决方案&#xff0c;潜在客户以多种…

【2023unity游戏制作-mango的冒险】-开始画面API制作

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;游戏制作 ⭐mango的冒险-开始画面制作⭐ 文章目录⭐mango的冒险-开始画面制作⭐&#x1f468;‍&…

EasyCVR视频云存储的架构解析与Sharelist云存挂载方法介绍

一、什么是视频云存储&#xff1f; 视频云存储主要用于为上层应用提供视频文件、结构化信息、事件信息的相关服务。云存储节点分为数据文件存储节点和结构化数据存储节点。数据文件存储节点主要用于视频、图片的存储。结构化数据存储节点用于存储结构化数据并提供相关服务。 …

【学习记录】PCA主成分分析 SVD奇异值分解

在看MSC-VO代码的过程中&#xff0c;大量出现了奇异值分解的内容&#xff0c;本身对这部分了解不多&#xff0c;这里补一下课&#xff0c;参考b站up主小旭学长的视频&#xff0c;链接为&#xff1a;PCA主成分分析和SVD主成分分析 PCA主成分分析 PCA根本目的在于让数据在损失尽…

机器学习笔记之生成模型综述(三)生成模型的表示、推断、学习任务

机器学习笔记之生成模型综述——表示、推断、学习任务引言生成模型的表示任务从形状的角度观察生成模型的表示任务从概率分布的角度观察生成模型的表示任务生成模型的推断任务生成模型的学习任务引言 上一节介绍了从监督学习、无监督学习任务的角度介绍了经典模型。本节将从表…

概率论面试题1:玫瑰花

概率论面试题 1. 一个活动&#xff0c;n个女生手里拿着长短不一的玫瑰花&#xff0c;无序的排成一排&#xff0c;一个男生从头走到尾&#xff0c;试图拿更长的玫瑰花&#xff0c;一旦拿了一朵就不能再拿其他的&#xff0c;错过了就不能回头&#xff0c;问最好的策略&#xff1…

3年自动化测试这水平?我还不如去招应届生

公司前段缺人&#xff0c;也面了不少测试&#xff0c;结果竟然没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-20k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。看简历很多都是3年工作经验&#xff0c;但面试…

什么是响应性?

响应性&#xff1a; 这个术语在今天的各种编程讨论中经常出现&#xff0c;但人们说它的时候究竟是想表达什么意思呢&#xff1f;本质上&#xff0c;响应性是一种可以使我们声明式地处理变化的编程范式。一个经常被拿来当作典型例子的用例即是 Excel 表格&#xff1a; 这里单元…

angular相关知识点总结

创建 angualr 组件和传值 angular组件其实就是个xxx.component.ts,本质还是ts文件一个html文件 1.创建组件&#xff1a;在Angular中&#xff0c;可以使用命令行工具ng generate component创建一个新组件。例如&#xff1a; ng generate component my-component这将创建一个名…

Ubuntu 系统下Docker安装与使用

Ubuntu 系统下Docker安装与使用Docker安装与使用Docker安装安装环境准备工作系统要求卸载旧版本Ubuntu 14.04 可选内核模块Ubuntu 16.04 使用 APT 安装安装 Docker CE使用脚本自动安装启动 Docker CE建立 docker 用户组测试 Docker 是否安装正确镜像加速Docker使用拉取镜像创建…

SPSS数据分析软件的安装与介绍(附网盘链接)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

SAP COPA 获利能力分析深度解析

一、获利分析配置及相关值概述 二、配置&#xff1a;组织结构 2.1 定义经营范围-KEP8 2.2 维护经营关注点-KEA0 2.3 获利能力分析类型解析 2.4 控制范围分配给经营范围-KEKK 三、配置&#xff1a;数据结构-KEA0 3.1 特征字段 3.1.1 特征字段类别 3.1.2 维护特征字段-K…

分类预测 | Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机森林多特征分类预测

分类预测 |Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机森林多特征分类预测 目录分类预测 |Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机森林多特征分类预测分类效果基本介绍模型描述程序设计参考资料分类效果 基本介绍 Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机…

C++学习笔记(四)

组合、继承。委托&#xff08;类与类之间的关系&#xff09; 复合 queue类里有一个deque&#xff0c;那么他们的关系叫做复合。右上角的图表明复合的概念。上图的特例表明&#xff0c;queue中的功能都是通过调用c进行实现&#xff08;adapter&#xff09;。 复合关系下的构造和…

CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图

CS5260测试版|CS5260demoboard|typec转VGA参考PCB原理图 CS5260是一款高度集成的TYPEC转VGA转换方案芯片。 CS5260输出端接口:外接高清VGA设备如:显示器投影机电视带高清的设备&#xff0c;广泛应用于 笔记本Macbook Air 12寸USB3.1输出端对外接高清VGA设备如:显示器投影机电视…

11.hadoop系列之MapReduce框架原理之InputFormat数据输入

我们先简要了解下InputFormat输入数据 1.数据块与数据切片 数据块&#xff1a; Block在HDFS物理上数据分块&#xff0c;默认128M。数据块是HDFS存储数据单位 数据切片&#xff1a; 数据切片只是在逻辑上对输入进行分片&#xff0c;并不会物理上切片存储。数据切片是MapReduce…

儿童书写台灯哪个牌子比较好?2023儿童护眼台灯分享

现在儿童的近视率高达52.7%&#xff0c;有科技水平的提高和电子产品的普及&#xff0c;近视率逐年攀升&#xff0c;出现低龄化现象&#xff0c;调查结果显示&#xff0c;其中6岁儿童达到14.3%&#xff0c;小学生为35.6%。初中生71.1%&#xff0c;高中生高达80.5%&#xff0c;可…

go语言rpc,grpc介绍

目录rpcRPC调用net/rpcRPC over HTTP 和 RESTfulserverclientRPC over TCP 和 RESTfulserverclient序列化/反序列化协议json序列化serverclientpython调用rpcRPC原理rpc框架比较grpcwhy gRpcgRPC与Protobuf介绍安装gRPC和Protobuf检查gRPC的开发方式编写proto代码编写Server端G…

Linux -文件系统操作与帮助命令

1、Linux -文件系统操作 df — 查看磁盘的容量 df -h —以人类可以看懂的方式显示磁盘的容量&#xff0c;易读 du 命令查看目录的容量 # 默认同样以块的大小展示 du # 加上 -h 参数&#xff0c;以更易读的方式展示 du -h-d 参数指定查看目录的深度&#xff1a; # 只查看 1…