一缀磕、react hook介紹
Hook 是 React 16.8 的新增特性。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性。目的是解決React的狀態(tài)邏輯復(fù)用問題,因?yàn)镽eact Hooks只共享數(shù)據(jù)處理邏輯芙盘,并不會(huì)共享數(shù)據(jù)本身。
在React應(yīng)用開發(fā)中脸秽,狀態(tài)管理是組件開發(fā)必不可少的內(nèi)容儒老。以前,為了對(duì)狀態(tài)進(jìn)行管理记餐,最通常的做法是使用類組件或者直接使用redux等狀態(tài)管理框架⊥苑現(xiàn)在,開發(fā)者可以直接使用React Hooks提供的State Hook來處理狀態(tài)片酝。
眾所周知囚衔,React提供了兩種創(chuàng)建組件的方式,即函數(shù)組件和類組件雕沿。函數(shù)組件是一個(gè)普通的JavaScript函數(shù)练湿,接受props對(duì)象并返回React元素,函數(shù)組件更符合React數(shù)據(jù)驅(qū)動(dòng)視圖的開發(fā)思想审轮。不過肥哎,函數(shù)組件缺乏類組件諸如狀態(tài)辽俗、生命周期等種種特性,而Hooks的出現(xiàn)就是讓函數(shù)式組件擁有類組件的特性贤姆。
為了讓函數(shù)組件擁有類組件的諸如狀態(tài)榆苞、生命周期等特性,React 提供了3個(gè)核心的api霞捡,即state hook 、Effect hook以及自定義 hook薄疚。
二碧信、react hook的使用方法
import React, { useState } form 'react';
function Example() {
????// useState 方法返回一個(gè)數(shù)組街夭。第一個(gè)值是當(dāng)前的 state砰碴,第二個(gè)值是更新 state 的函數(shù),相當(dāng)于類組件的setState板丽。
? ? const [count, setCount] = useState(0);
? ? return (
? ? ????<div>
? ? ? ??????<p>You clicked {count} times</p>
? ? ? ??????<button onClick={() => setCount(count + 1)}>點(diǎn)我加1</button>
? ? ????</div>
? );
}
如上示例呈枉,這個(gè)函數(shù)組件有自己的狀態(tài),并且還可以更新自己的狀態(tài)埃碱。useState用于創(chuàng)建一個(gè)新的狀態(tài)猖辫,參數(shù)為一個(gè)固定的值(初始值,作為useState的參數(shù)來將其初始化為 0)或者一個(gè)有返回值的方法砚殿。執(zhí)行后的結(jié)果為一個(gè)數(shù)組啃憎,分別為生成的狀態(tài)count以及改變?cè)摖顟B(tài)的方法setCount,通過解構(gòu)賦值的方法拿到對(duì)應(yīng)的值與方法似炎。
函數(shù)組件中如果存在多個(gè)狀態(tài)辛萍,既可以通過一個(gè)useState聲明對(duì)象類型的狀態(tài),也可以通過useState多次聲明狀態(tài)羡藐。
const [count, setCount] = useState({
? count1: 0,
? count2: 0
});
或者
const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(0);
三贩毕、Effect hook 的使用方法
Effect Hook 可以在函數(shù)組件中執(zhí)行副作用操作,主要用于以下兩種情況:
1.函數(shù)式組件中不存在傳統(tǒng)類組件生命周期的概念仆嗦,如果我們需要在一些特定的生命周期或者值變化后做一些操作的話辉阶,必須借助useEffect的一些特性去實(shí)現(xiàn)。
2.useState產(chǎn)生的 changeState 方法并沒有提供類似于setState的第二個(gè)參數(shù)一樣的功能欧啤,因此如果需要在 State 改變后執(zhí)行一些方法睛藻,必須通過useEffect實(shí)現(xiàn)。
該鉤子接受兩個(gè)參數(shù)邢隧,第一個(gè)參數(shù)為副作用需要執(zhí)行的回調(diào)店印,生成的回調(diào)方法內(nèi)可以返回一個(gè)函數(shù)(將在組件卸載時(shí)運(yùn)行);第二個(gè)為該副作用監(jiān)聽的狀態(tài)數(shù)組倒慧,當(dāng)對(duì)應(yīng)狀態(tài)發(fā)生變動(dòng)時(shí)會(huì)執(zhí)行副作用按摘,如果第二個(gè)參數(shù)為空包券,那么在每一個(gè) State 變化時(shí)都會(huì)執(zhí)行該副作用。
const?[count,?changeCount]?=?useState(0);
//?將在count變化時(shí)打印最新的count數(shù)據(jù)
useEffect(()=>?{
??message.info(`count發(fā)生變動(dòng)炫贤,最新值為${count}`);
},?[count])
在上面的例子中溅固,我們實(shí)現(xiàn)了利用useState實(shí)現(xiàn)了setState后執(zhí)行某個(gè)方法,那如果想要實(shí)現(xiàn)componentDidMount和componentWillUnmout生命周期的功能呢兰珍?
首先所有的副作用在組件掛載完成后會(huì)執(zhí)行一次 侍郭,如果副作用存在返回函數(shù),那么返回的函數(shù)將在卸載時(shí)運(yùn)行掠河。我們要做的就是讓與該副作用相關(guān)聯(lián)的狀態(tài)為空數(shù)組亮元,不管其他狀態(tài)如何變動(dòng),該副作用都不會(huì)再次執(zhí)行唠摹,于是就實(shí)現(xiàn)了componentDidMount和componentWillUnmout爆捞。
functionChild({?visible?}){
??useEffect(()=>?{
????message.info('我只在頁(yè)面掛載時(shí)打印');
????return?()=>?{
??????message.info('我只在頁(yè)面卸載時(shí)打印');
????};
??},?[]);
??return?visible???'true'?:?'false';
}
在上面示例中,我們實(shí)現(xiàn)了componentDidMount和componentWillUnmout勾拉,那么如何實(shí)現(xiàn)componentDidUpdate呢煮甥?其實(shí),只要第二個(gè)參數(shù)為空(注意不是上面示例中的空數(shù)據(jù)藕赞,而是不傳第二個(gè)參數(shù))成肘,那么在每一個(gè) State 變化時(shí)都會(huì)執(zhí)行該副作用了。
useEffect(()=>?{
?……
})
四找默、如何自定義Hook
眾所周知艇劫,要在類組件之間共享一些狀態(tài)邏輯是非常麻煩的,常規(guī)做法是通過高階組件或函數(shù)的屬性來解決惩激。不過店煞,新版的React允許開發(fā)者創(chuàng)建自定義Hook來封裝共享狀態(tài)邏輯,且不需要向組件樹中增加新的組件风钻。
所謂的自定義Hook顷蟀,其實(shí)就是指函數(shù)名以u(píng)se開頭并調(diào)用其他Hook的函數(shù),自定義Hook的每個(gè)狀態(tài)都是完全獨(dú)立的骡技。
export const useAxios = (url, dependencies) => {
? ? const [isLoading, setIsLoading] = useState(false);
? ? const [response, setResponse] = useState(null);
? ? useEffect(() => {
? ? ? ? setIsLoading(true);
? ? ? ? axios.get(url).then((res) => {
? ? ? ? ? ? setIsLoading(false);
? ? ? ? ? ? setResponse(res);
? ? ? ? }).catch((err) => {
? ? ? ? ? ? setIsLoading(false);
? ? ? ? });
? ? }, dependencies);
? ? return [isLoading, response, error];
};
使用自定義方法:
function Example() {
? let url = 'http://www.baidu.com/api/xxx';
? const [isLoading, response, error] = useAxios(url, []);
? ...
}
export default Example;
五鸣个、使用Hooks的注意事項(xiàng):
1.不要在循環(huán)、條件或嵌套函數(shù)中使用Hook布朦,并且只能在React函數(shù)的頂層使用Hook囤萤。因?yàn)镽eact需要利用調(diào)用順序來正確更新相應(yīng)的狀態(tài),以及調(diào)用相應(yīng)的生命周期函數(shù)函數(shù)是趴。一旦在循環(huán)或條件分支語(yǔ)句中調(diào)用Hook涛舍,就容易導(dǎo)致調(diào)用順序的不一致性,從而產(chǎn)生難以預(yù)料到的后果唆途。
2.只能在React函數(shù)式組件或自定義Hook中使用Hook富雅。