首頁> web前端> Vue.js> 主體

hooks怎麼樣,為什麼vue和react都選擇它!

青灯夜游
發布: 2022-03-02 10:09:19
轉載
2802 人瀏覽過

這篇文章我們來了解下hooks,聊聊為什麼vue和react都選擇它,為什麼我們需要 hooks ,以及vue 和 react 自訂 Hook 的異同,希望對大家有所幫助!

hooks怎麼樣,為什麼vue和react都選擇它!

閱讀本文,你將:

  • #初步了解Hooksvuereact的現況

  • 聽一聽本文作者關於Hooks的定義與總結

  • 弄清楚「為什麼我們需要Hooks

  • 進行一些簡單的Hooks實踐

一、hooks: 什麼叫大勢所趨?

2019年初,react16.8.x版本正式具備了hooks能力。

2019年6月,尤雨溪在vue/github-issues裡提出了關於vue3 Component API的提案。 (vue hooks的基礎)

在後續的reactvue3相關版本中,相關版本hooks能力都開始被更多人所接受。 【相關推薦:vuejs影片教學

除此之外,solid.jspreact等框架,也是開始選擇加入hooks大家庭。

hooks怎麼樣,為什麼vue和react都選擇它!

可以預見,雖然目前仍然是class Componenthooks api並駕齊驅的場面,但未來幾年裡,hooks極有可能取代class Component成為業界真正的主流。

二、什麼是hooks

年輕時你不懂我,就像後來我不懂hooks

2.1hooks的定義

"hooks" 直譯是“鉤子”,它並不僅是react,甚至不僅是前端界的專用術語,而是整個產業所熟知的用語。通常指:

系統運行到某一時期時,會呼叫被註冊到該時機的回呼函數。

比較常見的鉤子有:windows系統的鉤子能監聽到系統的各種事件,瀏覽器提供的onloadaddEventListener能註冊在瀏覽器各種時機被呼叫的方法。

以上這些,都可以被稱一聲 "hook"。

但是很顯然,在特定領域的特定話題下,hooks這個字被賦予了一些特殊的意義。

react@16.x之前,當我們談論hooks時,我們可能談論的是「元件的生命週期」。

但現在,hooks則有了全新的意義。

react為例,hooks是:

一系列以「use」開頭的方法,它們提供了讓你可以完全避開class式寫法,在函數式元件中完成生命週期、狀態管理、邏輯復用等幾乎全部元件開發工作的能力。

簡化一下:

一系列方法,提供了在函數式元件中完成開發工作的能力。

(記住這個關鍵字:函數式元件

import { useState, useEffect, useCallback } from 'react'; // 比如以上这几个方法,就是最为典型的 Hooks
登入後複製

而在vue中,hooks的定義可能更模糊,姑且總結一下:

vue組合式API裡,以“use”作為開頭的,一系列提供了元件復用、狀態管理等開發能力的方法。

(關鍵字:組合式API

import { useSlots, useAttrs } from 'vue'; import { useRouter } from 'vue-router'; // 以上这些方法,也是 vue3 中相关的 Hook!
登入後複製

如:useSlotsuseAttrsuseRouter等。

但主觀來說,我認為vue組合式API本身就是「vue hooks」的關鍵一環,起到了react hooks裡對生命週期、狀態管理的核心角色。 (如onMountedref等等)。

hooks怎麼樣,為什麼vue和react都選擇它!

如果按這個標準來看的話,vuereacthooks的定義,似乎都差不多。

那為什麼要提到是以「use」作為開頭的方法呢?

2.2 命名規範和指導思想

通常來說,hooks的命名都是以use作為開頭,這個規範也包括了那麼我們自訂的hooks

為什麼?

因为(爱情 误)约定。

react官方文档里,对hooks的定义和使用提出了“一个假设、两个只在”核心指导思想。(播音腔)

hooks怎麼樣,為什麼vue和react都選擇它!

一个假设:假设任何以 「use」 开头并紧跟着一个大写字母的函数就是一个Hook

第一个只在:只在React函数组件中调用Hook,而不在普通函数中调用Hook。(Eslint通过判断一个方法是不是大坨峰命名来判断它是否是React函数)

第二个只在:只在最顶层使用Hook,而不要在循环,条件或嵌套函数中调用 Hook。

因为是约定,因而useXxx的命名并非强制,你依然可以将你自定义的hook命名为byXxx或其他方式,但不推荐。

因为约定的力量在于:我们不用细看实现,也能通过命名来了解一个它是什么。

以上“一个假设、两个只在”总结自react官网:

  • https://zh-hans.reactjs.org/docs/hooks-rules.html

  • https://zh-hans.reactjs.org/docs/hooks-faq.html#what-exactly-do-the-lint-rules-enforce

三、为什么我们需要hooks?

3.1 更好的状态复用

怼的就是你,mixin

class组件模式下,状态逻辑的复用是一件困难的事情。

假设有如下需求:

当组件实例创建时,需要创建一个state属性:name,并随机给此name属性附一个初始值。除此之外,还得提供一个setName方法。你可以在组件其他地方开销和修改此状态属性。

更重要的是: 这个逻辑要可以复用,在各种业务组件里复用这个逻辑。

在拥有Hooks之前,我首先会想到的解决方案一定是mixin

代码如下:(此示例采用vue2 mixin写法 )

// 混入文件:name-mixin.js export default { data() { return { name: genRandomName() // 假装它能生成随机的名字 } }, methods: { setName(name) { this.name = name } } }
登入後複製
// 组件:my-component.vue