Hooks是什么?為啥Vue和React都選擇了它?
Hooks是什么
"hooks" 直譯是 “鉤子”,它并不僅是 react,甚至不僅是前端界的專用術(shù)語,而是整個(gè)行業(yè)所熟知的用語。通常指:系統(tǒng)運(yùn)行到某一時(shí)期時(shí),會(huì)調(diào)用被注冊到該時(shí)機(jī)的回調(diào)函數(shù)。
為啥要用Hooks
- 跨組件復(fù)用stateful logic十分困難 使用Hooks,你可以在將含有state的邏輯從組件中抽象出來,這將可以讓這些邏輯容易被測試。同時(shí),Hooks可以幫助你在不重寫組件結(jié)構(gòu)的情況下復(fù)用這些邏輯。
- 復(fù)雜的組件難以理解 Hooks允許您根據(jù)相關(guān)部分(例如設(shè)置訂閱或獲取數(shù)據(jù))將一個(gè)組件分割成更小的函數(shù),而不是強(qiáng)制基于生命周期方法進(jìn)行分割。
- 不止是用戶,機(jī)器也對Classes難以理解 Hooks讓你可以在classes之外使用更多React的新特性。
Hooks的優(yōu)點(diǎn)
更好的狀態(tài)復(fù)用
假設(shè)有如下需求:
當(dāng)組件實(shí)例創(chuàng)建時(shí),需要?jiǎng)?chuàng)建一個(gè) state 屬性:name,并隨機(jī)給此 name 屬性賦值一個(gè)初始值。除此之外,還得提供一個(gè) setName 方法。你可以在組件其他地方開銷和修改此狀態(tài)屬性。
更重要的是: 這個(gè)邏輯要可以復(fù)用,在各種業(yè)務(wù)組件里復(fù)用這個(gè)邏輯。
在擁有 Hooks 之前,我首先會(huì)想到的解決方案一定是 mixin。
代碼如下:(此示例采用 vue2 mixin 寫法 )。
// 混入文件:name-mixin.js
export default {
data() {
return {
name: genRandomName() // 假如它能生成隨機(jī)的名字
}
},
methods: {
setName(name) {
this.name = name
}
}
}
// 組件:my-component.vue
<template>
<div>{{ name }}</div>
<template>
<script>
import nameMixin from './name-mixin';
export default {
mixins: [nameMixin],
// 通過mixins, 你可以直接獲得 nameMixin 中所定義的狀態(tài)、方法、生命周期中的事件等
mounted() {
setTimeout(() => {
this.setName('Tom')
}, 3000)
}
}
<script>
雖然看起來好像是可以復(fù)用的,但是React官方出來說話了。
既然被斃了,肯定是有它的原因的,雖然是可以實(shí)現(xiàn)復(fù)用,但是顯露的弊端也是非常的明顯的。
方法和屬性難以監(jiān)聽
export default {
mixins: [ a, b, c, d, e, f, g ], // 當(dāng)然,這只是表示它混入了很多能力
mounted() {
console.log(this.name)
// mmp!這個(gè) this.name 來自于誰?我難道要一個(gè)個(gè)混入看實(shí)現(xiàn)?
}
}
屬性、方法會(huì)覆蓋
當(dāng)我同時(shí)想混入 mixin-a.js 和 mixin-b.js 以同時(shí)獲得它們的屬性或者方法的時(shí)候,比較尷尬的事情發(fā)生了:由于這兩個(gè) mixin 功能的開發(fā)者心有靈犀,它們都定義了 this.name 作為屬性。這種時(shí)候,這個(gè)時(shí)候的你就會(huì)傻傻分不清。
代碼結(jié)構(gòu)
這就是為啥Vue3尤大大使用CompostionAPI的原因了。
這樣帶來的好處是顯而易見的:“高度聚合,可閱讀性提升”。伴隨而來的便是 “效率提升,bug變少”。
趨勢
2019年年初,react 在 16.8.x 版本正式具備了 hooks 能力。2019年6月,尤雨溪在 vue/github-issues 里提出了關(guān)于 vue3 Component API 的提案。(vue hooks的基礎(chǔ))在后續(xù)的 react 和 vue3 相關(guān)版本中,相關(guān) hooks 能力都開始被更多人所接受。除此之外,solid.js、 preact 等框架,也是開始選擇加入 hooks 大家庭。