有关如何创建简单的 React 自定义钩子的教程。在编写 React 函数式组件时,如果我们想重用组件的部分逻辑,我们可以考虑编写自定义 Hooks。
首先,让我们来看看 React 钩子。钩子只是 JavaScript 函数,但是在 React 中使用它们时,你需要遵循规则:
仅在顶层调用钩子
仅从 React 函数调用钩子
第一点与 React Hook 的实现原理有关。当函数组件第一次执行时,react分配一个对象,当一个接一个地调用钩子时,获得的结果依次放入有序表中,然后存储在对象中。
对于后续的执行,这些钩子的执行顺序必须相同,以便比较依赖关系并与先前渲染的状态进行比较。
如果钩子出现在循环、条件或嵌套函数中...不能保证钩子的执行顺序不会保持不变。
第二点意味着你应该总是从 React 函数组件调用钩子,而不是类组件或常规的 JavaScript 函数,但如果它是一个自定义 Hook,那么从中调用钩子也是合法的。
自定义钩子是具有唯一命名约定的 JavaScript 函数,该约定要求以函数名称开头 ,并且能够调用其他钩子。use
这听起来很麻烦,我将尝试用一个简单的 React 示例来说明这一点。在下面的代码示例中,我们将在组件内获取并显示图像/ gif。
首先,让我们看一下这个简单应用程序应该是什么样子的最终结果,我们有两个组件彼此叠加,顶部名为 RandomGif,底部名为 SearchImg。
最终结果
这两个组件都在 App.js内:
随机极谱和搜索磁共振组件
组件名称说明了一切,随机GIF显示随机GIF,搜索Img为用户提供了使用输入字段值搜索图像的可能性。 我们将使用两个 API 端点(Giphy 和 Pixabay),访问密钥将在我们注册时自动生成。
现在,从随机Gif组件开始,*下面的API_KEY存储在.env文件中。
搜索模块组件:
正如我们所看到的,RandomGif和ScerImg之间的逻辑基本上是相同的,唯一的区别是我们使用两个不同的端点,在SearchImg组件中有一个输入字段和一个onChange事件处理程序,它以输入值为目标,并使用户能够通过值查询来搜索图像, 更容易解释的是,在同一API调用逻辑中有不同的参数。
创建这样的组件很简单,但是如果我们有更多的组件,我们在其中进行相同的API调用但具有不同的参数,我们不想复制相同的代码并将其粘贴到每个组件中,对吧?
一个好的解决方案是自定义一个 Hook 来封装组件之间并共享相同的逻辑,如 React Hooks 简介所示:
自定义钩子是一个 JavaScript 函数,其名称以“use”开头,可以调用其他钩子。 (例如: useFetch )
让我们为上面的这个例子创建一个自定义的钩子,我将它命名为useFetch
在上面的代码中,我们创建了一个名为包含函数的新文件,其中包含获取数据所需的所有逻辑。逻辑是从组件中复制的( fetchGif / fetchImg ),我们只是删除了硬编码的URL,并将它们替换为可以传递给自定义 Hook 的变量。useFetch.jsuseFetchurl
自定义 Hook 不需要有特定的签名,我们可以决定它接受什么作为参数,以及它应该返回什么(如果有的话),在这种情况下:(url)和return [{ img }, fetchImg]
返回值 { img } 是初始化为 null 的 img 状态,将在组件内导入和使用
函数 fetchImg 将被导入并在组件内部使用
而且,正如钩子介绍中所示,从自定义钩子调用预定义的 React 库 Hook 是合法的,因此我们在这里使用了 useState 钩子,它在两个组件中完全相同。
现在我们可以更新这两个组件并使用此自定义钩子:
上面的代码解释道:
我们导入我们的定制钩子
使用从我们的自定义钩子返回的状态和获取函数
请注意,这里的 fetchImg 函数不用于更新“img”状态,它是来自 useFetch 自定义钩子的提取函数,可以在另一个函数中调用,在这种情况下,按钮 onClick 事件为“const SearchImg = () = > fetchImg()”和“const getRandomGif = () = > fetchImg()”。
到目前为止,应用程序中没有任何更改,但现在我们可以在任何组件中重用此自定义钩子,只要它们使用相同的逻辑,就可以从任何URL获取数据。使用自定义钩子,我们可以将组件逻辑提取到可重用的函数中。