首页 > 其他分享 >Hooks与普通函数的区别

Hooks与普通函数的区别

时间:2022-10-16 11:55:11浏览次数:41  
标签:函数 自定义 区别 url Hooks 普通 数据

Hooks与普通函数的区别

在这里的Hooks具体指的是自定义Hooks,自定义的Hooks与我们定义的普通函数类似,都可以封装逻辑,以实现逻辑的复用。Hooks实际上是一种特殊的函数,而由于Hooks的特殊实现,他们之间也存在着一定的区别。

描述

在我开始学习React Hooks的时候,我就比较疑惑这个问题。首先看一下官方文档,在自定义Hooks的部分说明了,构建自己的Hooks可以让您将组件逻辑提取到可重用的函数中。如果仅仅是这样的话,那么我们也完全可以使用普通的函数来实现逻辑的复用,而没必要去使用Hooks了。
当然在这里还是得先明确一点定义: 自定义Hooks就是很明确的定义了,其以use开头,内部可以调用其他的Hooks;在这里描述的的普通函数指的是我们平时写的抽离公共逻辑的函数,而不是在我们定义的普通函数中去调用其他Hooks这种方式。如果在普通函数中调用了其他Hooks,那么这个函数就不再是普通函数了,除了违反了Hooks的命名规则以外,那就完全是一个Hooks的定义了。
实际上,Coding比较重要的两个概念是逻辑与数据,文档中提到的将组件逻辑提取到可重用的函数中,重要的是逻辑这两个字,而在两个组件中使用相同的自定义Hooks是不会共享State的。如果我们直接编写一个普通的函数,那么对于其数据是在所有调用者中共享的,因为其只是一个模块,当然前提是我们不会去new出一个新对象来保存状态,在这里只讨论最plain的调用方式,因为Hooks也是直接以非常plain的方式进行调用的。
那么也就是说,如果我们使用Hooks的话,实际上由于可以调用useStateuseRefHooks,从而获取了对于这个Fiber的访问方法,那么也就相当于我们可以将状态或者说数据存放于当前节点当中,而不是类似于普通函数在全局中共享。当然如果需要全局共享状态的话,状态管理方案是更好的选择,而不是全局变量。

示例

举一个例子,对于数据请求,我们通常会封装一个request函数,假如我们需要对这个函数做一层缓存,那么就会有逻辑与数据的复用,在逻辑方面我们抽离出的方法差距不大,而对于数据缓存复用方面在这里通过普通函数与自定义Hooks的实现便是不同的。

普通函数

在普通函数当中,其就是一个模块,因此其数据是在所有调用者中共享的,因此我们可以通过一个Map来存储数据,这样就可以实现数据的复用。在这里需要注意的是,如果我们的url需要实现在不同组件调用返回的数据不同的话,例如可能会有根据当前页面的referer请求头来决定返回数据的需求,那么这种全局共享的数据就不适用了,就需要多添加一个参数来区分不同的数据,这样就会导致逻辑与数据的耦合,因此这种方式不是很好。当然这也是基于特定需求的,在这里只是举一个例子,毕竟实际上适合的才是最好的。

const cache = new Map();
export fetch = (url) => {
  if (cache.has(url)) {
    return cache.get(url);
  }
  const promise = fetch(url);
  cache.set(url, promise);
  return promise;
}

自定义Hooks

在自定义Hooks当中,数据被锁定在了Fiber当中,也就是说数据的共享范围是在当前组件节点中,相对于全局状态共享来说粒度会更细一些。当然我们如果想直接在全局共享数据的话,这种方案就不合适了,可能还需要配合一个全局的状态管理才行。还是那句话,在这里只是举一个例子,毕竟实际上适合的才是最好的。

const useRequest = (url) => {
    const map = useRef(new Map());
    if (map.current.has(url)) {
        return map.current.get(url);
    }
    const promise = fetch(url);
    map.current.set(url, promise);
    return promise;
}

总结

简单总结一下两者的区别:

  • 官方提供的Hooks只应该在React函数组件/自定义Hooks内调用,而不应该在普通函数调用。
  • 自定义Hooks能够调用诸如useStateuseRef等,普通函数则不能。由此可以通过内置的Hooks获得Fiber的访问方式,可以实现在组件级别存储数据的方案等。
  • 自定义Hooks需要以use开头,普通函数则没有这个限制。使用use开头并不是一个语法或者一个强制性的方案,更像是一个约定,就像是GET请求约定语义不携带Body一样,使用use开头的目的就是让React识别出来这是个Hooks,从而检查这些规则约束,通常也会使用ESlint配合eslint-plugin-react-hooks检查这些规则,从而提前避免错误的使用。

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://www.zhihu.com/question/491311403
https://zh-hans.reactjs.org/docs/hooks-custom.html
https://stackoverflow.com/questions/60133412/react-custom-hooks-vs-normal-functions-what-is-the-difference

标签:函数,自定义,区别,url,Hooks,普通,数据
From: https://www.cnblogs.com/WindrunnerMax/p/16795892.html

相关文章

  • C语言之字符串与字符数组的区别
     1.字符串的定义:(1)单个字符:charch='i';//单个字符的定义(2)一维字符串数组:chararr[]="love";(这种方法定义的一维字符串数组必须赋值)chararr[4];(想内存申请创建可以......
  • union all和union的区别用法
    unionall和union的区别:取结果的交集,union对两个结果集进行并集操作,不包括重复行,相当于distinct,同时进行默认规则的排序;unionall:对两个结果集进行并集操作,包括重复行,即所......
  • 布隆过滤器是否好用,得看哈希函数写成啥样
    作者:小傅哥沉淀、分享、成长,让自己和他人都能有所收获!......
  • 《流畅的Python第二版》读书笔记——函数作为一等对象
    引言这是《流畅的Python第二版》抢先版的读书笔记。Python版本暂时用的是python3.10。为了使开发更简单、快捷,本文使用了JupyterLab。函数是Python的一等(first-class)对象......
  • 函数的内置方法
    内置函数就是python给你提供的,拿来直接用的函数.截至到python版本3.6.2python一共提供了68个内置函数,他们就是python直接提供给我们的.作用域相关locals()返回当前作......
  • 函数的初步认识及注意
    1.应该定义在main函数外面,就是写在源文件下面2.语法 返回值类型函数名(【参数列表】)      {       写上被调用的代码(简称函数体)     ......
  • 爬取spa网站与ssr网站的区别
    前言在练习爬虫的时候不清楚spa与ssr网站的区别,都使用bs4直接解析网页的html,结果ssr网站输出结果,spa网站却没有输出结果,特此记录ssr网站:https://ssr1.scrape.center/page......
  • utf8与utf8mb4之间的区别
    刚才在navigate中创建表格时未找到utf8,但看到了比较相似的utf8mb4.所以对这两个编码之间的区别进行了搜索,得到总结,可以将utf8mb4看成utf8的升级版。以下是搜索到的资料......
  • Docker | dockerfile构建centos镜像,以及CMD和ENTRYPOINT的区别
    构建自己的centos镜像dockerpullcentos下载下来的镜像都是基础版本,缺少很多常用的命令功能,比如:ll、vim等等,下面介绍制作一个功能较全的自己的centos镜像。步骤1、编......
  • 【C++】统计string里面出现的字符的个数(使用count函数)
    题目:给出一个string字符串,统计里面出现的字符的个数解决方案:使用算法库<algorithm>里面的count函数(不是s.count()!!count是单独作为一个函数,而不是作为一个方法),使用方法是......