目录
"hooks" 直译是 “钩子”,它并不仅是 react,甚至不仅是前端界的专用术语,而是整个行业所熟知的用语。通常指:
系统运行到某一时期时,会调用被注册到该时机的回调函数。
比较常见的钩子有:windows 系统的钩子能监听到系统的各种事件,浏览器提供的 onload 或 addEventListener 能注册在浏览器各种时机被调用的方法。
以上这些,都可以被称一声 "hook"。
但是很显然,在特定领域的特定话题下,hooks 这个词被赋予了一些特殊的含义。
react@16.x 之前,当我们谈论 hooks 时,我们可能谈论的是“组件的生命周期”。react 为例,hooks 是:一系列以 “use” 作为开头的方法,它们提供了让你可以完全避开 class式写法,在函数式组件中完成生命周期、状态管理、逻辑复用等几乎全部组件开发工作的能力。(一系列方法,提供了在函数式组件中完成开发工作的能力。) - import { useState, useEffect, useCallback } from 'react';
- // 比如以上这几个方法,就是最为典型的 Hooks
vue 中, hooks 的定义可能更模糊:在 vue 组合式API里,以 “use” 作为开头的,一系列提供了组件复用、状态管理等开发能力的方法。 - import { useSlots, useAttrs } from 'vue';
- import { useRouter } from 'vue-router';
- // 以上这些方法,也是 vue3 中相关的 Hook!

在 react 官方文档里,对 hooks 的定义和使用提出了 “一个假设、两个只在” 核心指导思想
一个假设: 假设任何以 「use」 开头并紧跟着一个大写字母的函数就是一个 Hook。
第一个只在: 只在 React 函数组件中调用 Hook,而不在普通函数中调用 Hook。(Eslint 通过判断一个方法是不是大坨峰命名来判断它是否是 React 函数)
第二个只在: 只在最顶层使用 Hook,而不要在循环,条件或嵌套函数中调用 Hook。
因为是约定,因而 useXxx 的命名并非强制,你依然可以将你自定义的 hook 命名为 byXxx 或其他方式,但不推荐。
因为约定的力量在于:我们不用细看实现,也能通过命名来了解一个它是什么。
在 react 项目中, react 的版本需要高于 16.8.0。
而在 vue 项目中, vue3.x 是最好的选择,但 vue2.6+ 配合 @vue/composition-api,也可以开始享受“组合式API”的快乐。
Hooks 写法因为 react Hooks 仅支持“函数式”组件,因此需要创建一个函数式组件 my-component.js。
- // my-component.js
- import { useState, useEffect } from 'React'
-
- export default () => {
- // 通过 useState 可以创建一个 状态属性 和一个赋值方法
- const [ name, setName ] = useState('')
-
- // 通过 useEffect 可以对副作用进行处理
- useEffect(() => {
- console.log(name)
- }, [ name ])
-
- // 通过 useMemo 能生成一个依赖 name 的变量 message
- const message = useMemo(() => {
- return `hello, my name is ${name}`
- }, [name])
-
- return <div>{ message }</div>
- }
Hooks 写法vue 的 Hooks 写法依赖于 组合式API,因此本例采用 <script setup> 来写:
- <template>
- <div>
- {{ message }}
- </div>
- </template>
- <script setup>
- import { computed, ref } from 'vue'
- // 定义了一个 ref 对象
- const name = ref('')
- // 定义了一个依赖 name.value 的计算属性
- const message = computed(() => {
- return `hello, my name is ${name.value}`
- })
- </script>
很明显,vue 组合式API里完成 useState 和 useMemo 相关工作的 API 并没有通过 useXxx 来命名,而是遵从了 Vue 一脉相承而来的 ref 和 computed。