反应自定义挂钩与普通函数,有什么区别

我正在努力理解定制的钩子。我理解正常的钩子,这很好,但我的问题是,当编写一个自定义钩子时,它和正常的函数有什么区别?我的意思是,为什么不把它称为一个普通函数,而是把它称为 use * 这样的函数呢

20815 次浏览

自定义钩子依赖于另一个钩子。根据设计,React 钩子意味着从组件的呈现方法中使用。如果您尝试在其他任何地方使用钩子,都会得到警告。自定义钩子遵循与内置钩子相同的约定,因为它们必须以相同的方式使用。use前缀只是标识钩子函数的一种约定,这些函数通常在组件呈现方法的最顶端调用。

你可以命名你的钩子函数任何你想要的,但正如我提到的,你会得到一个警告,从反应,如果使用之外的渲染方法。

来自反应 医生:

自定义 Hook 是一个 JavaScript 函数,其名称以“ use”开头,可以调用其他 Hook。[ ... ]它的名字应该总是以“ use”开头,这样你一眼就能看出 胡克斯法则适用于它。

那么,为什么要用一个特殊的“ use”命名前缀来定义自定义 Hooks 呢?

1)它告诉消费者,这些函数将与 React 一起使用,并遵守隐式契约(上面提到的规则)。

2)您可以拥有检查和执行这些规则的工具支持。例如,eslint-plugin-react-hooks使用了一个 启发式的,它假定一个以“ use”前缀开头的函数和一个大写字母在它是 Hook 之后。

React Hook (自定义或非自定义)应该以 use前缀开头。同样,根据 React 文档:

1)钩子应该从 React 代码中调用,而不是从普通的 JS 函数中调用。因此,Hooks 的作用域仅限于 React 代码世界,并且对 React 代码有更大的作用。与 JS 不同,常规函数可以跨应用程序使用,但是作为反应代码指南,它使代码更符合反应语法。

2)在基于类的组件中,Hook 不能工作,但是常规函数可以。

3)在常规的 JS 函数中,你不能访问 useStateuseEffectuseContext等等,但是在反应中我可以访问自定义挂钩。

我相信没有人能准确地回答你的问题。我仍然理解使用这个称为 hook 的额外特性的好处和目的,但是我仍然可以分享我的理解。

React Hook 是一个 JS 函数,它的功能是做出反应,这意味着你可以添加一些逻辑,你也可以添加到一个普通的 JS 函数中,但是你也可以使用本地的 Hook,比如 useState,useEffect,等等,来启动这个逻辑,添加它的状态,或者添加它的副作用,制表或者更多。 因此,我相信钩子是一个非常好的东西,可以用一种独立的方式来管理组件的逻辑。

因此,您可以拥有一个 foo.Component ent.js (UI)、一个 useFoo.js (Logic) ,其中 useFoo 可能包含许多 js 函数和一个钩子来管理这些函数并返回它所期望的结果。

这是一个关于反应挂钩的令人惊讶的视频,完全推荐

Https://youtu.be/j-g9zjha8fe

有一些差异和问题,使我们使用反应自定义挂钩:

  1. 首先,如果使用普通函数,每次重新呈现组件时,都会重新创建这个函数,从而导致性能下降。你可能认为这个问题可以通过使用 useCallBack来解决,并且使得每次重新呈现的时候不要去创建一个新的函数,但是这不是我们要解决的主要问题。
  2. 通过一个简单的跟踪在线好友的例子,我们讨论了该反应文档的主要问题,即避免在不同的功能组件中复制粘贴相同的逻辑,因为这些组件也需要具有状态。
  3. 如果我们在一个组件中使用普通函数,并且每次都使用 useCallBack来避免创建新函数,那么我们并没有解决这个问题,因为在每个组件中我们都应该复制这个逻辑,所以这并没有解决问题。
  4. 另一个解决方案是在函数组件之外创建一个函数来处理这个逻辑,但是在组件的正常函数 在外面中有一个 大问题: 我们无权进入各州,因为正如我们提到的,这个实现的逻辑是有状态的,我们只能访问反应组件中的状态。

那么这里的解决方案是什么? 是的,自定义反应钩!

  1. 它是一个使用其他反应内置钩子(如 useStateuseCallback等)的 状态函数状态函数,它可以包围您想要在一个地方收集的有状态逻辑,并避免在多个组件中复制和粘贴相同的逻辑。
  2. 使用这种方法,您可以将您的逻辑放在组件之外的另一个函数中,同时您可以从有状态功能的 response 中获益。

我希望这个答案可以解决你的问题,解决你的模棱两可。

你可以随便叫它什么,它仍然会工作得很好。唯一的好处是,如果您使用“ useName”约定,React 将检查它是否正确地遵循了 Hook 的规则。只是让你的任务稍微容易一点。

正如其他用户指出的那样,一般来说,自定义钩子或钩子用于我们必须做任何与反应组件相关的事情的地方,而其他 util 函数没有绑定到反应状态,并且不会工作的地方是反应状态逻辑就位的地方。

自定义挂钩的一个例子是 useCustomNavigationwhich 可以是一个导航器函数的列表,如导航到主页,导航到检查等。所以当你从代码的不同部分路由到主页时,我们只需要使用这个钩子。此外,任何逻辑/特性(如分析)和副作用都可以作为导航 ToHome 功能的一部分。

Util 函数的一个例子可以是任何类似于大写的东西,它不必与反应或反应组件做任何事情。不能创建名为导航器的 util 函数并添加 useNavigator。

在我看来,自定义挂钩有自己的特定用途,有自己的特点和方法。 我的意思是,在某些情况下,我们希望创建一个自定义钩子,而不是一个函数。

例如,如果你需要在 LocalStorage 中存储一些数据,你需要为它创建一个自定义钩子,并将其命名为“ useLocalStorage”。如果你想创建一个组件,比方说一个页面表单,你需要编写一个函数组件。

不同之处在于,我们的钩子不是一个组件,并且在 UI 中不显示任何内容。 这只是一个简单的逻辑操作。

我认为它们与上面的“逻辑”示例不同的原因是,我们的自定义钩子在允许使用其他自定义钩子相关钩子方面是独一无二的。例如,“ useDebugValue”只能在自定义钩子中工作。

令我感到奇怪的是 React 区分函数和自定义钩子的方式,我认为这是造成混淆的主要原因。 它“检查”你的函数名,如果它以“ use”开头,那么它就是一个自定义钩子。我认为更好的选择是将“ const”声明更改为“ hook”声明或赋予其唯一类型。

DR,自定义钩子是逻辑,允许使用钩子,如“ useDebugValue”,我们的函数大多与 UI 相关。