希沃ENOW大前端javascript
公司官網:CVTE(廣州視源股份)css
團隊:CVTE旗下將來教育希沃軟件平臺中心enow團隊html
本文做者:前端
在聽到這麼一個問題的時候,首先腦海中整體思路是這樣子的:java
Hook
的基本概念Hook
進行復用邏輯的封裝Hook
的最佳實踐與工做原理Hook
底層原理思想Reack Hook
思想Hook
是 React 16.8
的新增特性。它可讓你在不編寫 class
的狀況下使用 state
以及其餘的 React
特性。React
官方提供了經常使用的StateHook
和EffectHook
分別用以管理函數式組件狀態和反作用。(React Hook官方介紹)。react
除了官方提供的StateHook和EffectHook外,咱們能夠本身將經常使用的組件邏輯抽取到可重用的函數中,該函數須以React約定的形式來命名與使用,用以共享組件邏輯。git
經過一個簡單的例子來看一下 好比咱們須要在拿到某個數據後設置頁面標題,並且須要在各個頁面裏面使用github
import React, { useState, useEffect } from 'react';
export default function App() {
// 正常咱們這樣子實現
const [title, setTitle] = useState('默認標題')
useEffect(() => {
document.title = title;
}, [title]);
const onTitleChange = (event) => {
setTitle(event.target.value);
}
return (<div> <h2>{title}</h2> <input type="text" onInput={onTitleChange}/> </div>)
}
複製代碼
export function useSetPageTitle (initTitle) {
const [title, setTitle] = useState(initTitle || '默認標題');
useEffect(() => {
document.title = title;
}, [title]);
return [title, setTitle]
}
複製代碼
import { useSetPageTitle } from '../App';
export default function Chirld() {
// 這裏使用剛纔寫自定義Hook
const [title, setTitle] = useSetPageTitle();
return (<div> <h2>{title}</h2> <input type="text" onInput={onTitleChange}/> </div>>)
}
複製代碼
這樣子一個自定義的hook
就成型了,是否是瞬間感受逼格提升了,原來我也能夠寫個這麼高大上的自定義Hook
,哈哈哈。npm
聰明的大家必定發現了下面的特色數組
Hook
必須以 use
開頭上面的例子中使用【useSetPageTitle】
。不遵循的話,因爲沒法判斷某個函數是否包含對其內部 Hook
的調用,React 將沒法自動檢查你的 Hook
是否違反了 Hook
的規則。
Hook
可自由搭配其餘hook
使用你能夠自由使用其餘內部Hook
和其餘自定義Hook
.上面演示例子中使用useState
和useEffect
.
這樣作是爲了確保 Hook
在每一次渲染中都按照一樣的順序被調用。若是不是最頂層會致使狀態或者執行方法出錯進而致使BUG
。
當state='A'
條件知足時執行調用Hook
順序是正常,當後續渲染條件不知足時,則React
調用Hook
順序出錯,則會致使方法和狀態邏輯執行出錯。
import React, { useState, useEffect } from 'react';
import './App.css';
import { useSetPageTitle } from './hooks';
export default function App() {
const [state, setState] = useState('A');
// 反例
if (state === 'A') {
useEffect(() => {
console.log('只執行一次')
}, [state]);
}
useState({});
useEffect(() => {
// 獲取數據
}, []);
useState({});
console.log(title)
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
複製代碼
import React, { useState, useEffect } from 'react';
export default function App() {
const [state, setState] = useState('A');
useEffect(() => {
if (state === 'A') {
console.log('執行相應的邏輯')
}
}, [state]);
useState({});
useEffect(() => {
// 獲取數據
}, []);
useState({});
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
複製代碼
爲了不出錯咱們可使用ESLint插件來檢測強制執行這些規則。 另外,親測React官方提供的create-react-app @3.x與@4.x在eject後已經集成了插件
eslint-plugin-react-hooks
複製代碼
// 你的 ESLint 配置
{
"plugins": [
// ...
"react-hooks"
],
"rules": {
// ...
"react-hooks/rules-of-hooks": "error", // 檢查 Hook 的規則
"react-hooks/exhaustive-deps": "warn" // 檢查 effect 的依賴
}
}
複製代碼
自定義 Hook
解決了之前在React
組件中沒法靈活共享邏輯的問題。那麼業務開發中可建立各類的自定義Hook
,公共輔助函數、狀態複用、邏輯複用、效果複用、操做複用、生命週期模擬以及多種組合複用等只有想不到,相信很難有這麼聰明的大家作不到的場景實現。
下面舉幾個簡單栗子,拋磚引玉
useMount
模擬生命週期componentDidMount
import React, { useState, useEffect } from 'react';
function useMount (fn) {
useEffect(() => {
fn();
}, []);
}
export default function App() {
useMount(() => {
// 你的邏輯
})
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
複製代碼
useEffect
返回函數是銷燬才調用的機制來模擬unmount
function useUnmount (fn) {
useEffect(() => {
return () => {
fn();
}
}, []);
}
export default function App() {
useUnmount(() => {
console.log('銷燬組件時輸出')
})
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
複製代碼
import React, { useState, useEffect } from 'react';
function useOnResize (fn) {
useEffect(() => {
window.addEventListener('resize',fn);
return () => {
window.removeEventListener('resize',fn)
}
}, []);
}
export default function App() {
useOnResize(() => {
console.log(document.body.clientWidth)
})
return (
<div className="App"> <p> Hello React Hook! </p> </div>
);
}
複製代碼
由螞蟻 umi 團隊、淘系 ice 團隊以及阿里體育團隊共同建設的 React Hooks 工具庫ahooks
Set of a helpful hooks, for different specific to some primitives types state changing helpers.
可使建立彈窗,提示,菜單變得很是容易,提供了建立DOM層次以外的元素的功能
用於發起Http請求的優秀Hook
發現更多優秀Hook庫可在下面評論貼上,整一個優秀Hooks庫的集合。
筆者並無實際看過React源碼,僅看過一些React Hook工做原理的文章。 這裏拋轉引玉,看過幾個比較好來分享。歡迎留言更多優秀實踐和原理剖析。
迎(bu)接(yao)新(geng)輪(xin)子(le),向(biao)着(shi)新(xue)輪(bu)子(dong)前(le)進