Hook 是 React 16.8 的新增特性嚼沿,它可以讓我們在不編寫class的情況下使用state以及其他的React特性(比如生命周期)
1.什么情況下使用Hooks
官方并不建議我們把原有的 class 組件汰翠,大規(guī)模重構成 Hooks驹碍,而是有一個漸進過程:
首先县貌,原有的函數組件如果需要自己的狀態(tài)或者需要訪問生命周期函數,那么用 Hooks 是再好不過了紊馏;
另外就是硬贯,我們可以先在一些邏輯較簡單的組件上嘗試 Hooks ,在使用起來相對較熟悉掸驱,且組內人員比較能接受的前提下肛搬,再擴大 Hooks 的使用范圍。
2.對比與class毕贼,函數式組件有哪些優(yōu)勢
State Hook 使得組件內的狀態(tài)的設置和更新相對獨立温赔,這樣便于對這些狀態(tài)單獨測試并復用。
Hook 將組件中相互關聯(lián)的部分拆分成更小的函數(比如設置訂閱或請求數據)帅刀,而并非強制按照生命周期劃分让腹,這樣使得各個邏輯相對獨立和清晰
3.hooks 提供的常用的幾個函數
(1) useState
useState來自react,需要從react中導入扣溺,它是一個hook
useState 只在初始化時執(zhí)行一次骇窍,后面不再執(zhí)行
u? 參數:初始化值,如果不設置為undefined; 返回值:數組锥余,包含兩個元素;
? 元素一:當前狀態(tài)的值(第一調用為初始化值); 類比于 state中的值
? 元素二:設置狀態(tài)值的函數;類比于 setState 更新界面
如下代碼
const [counter,setCount] = useState(0) //數組的結構
return (
<div>
<h2>當前計數 {counter}</h2>
<button onClick={e => setCount( counter + 1 )}>+1</button>
<button onClick={e => setCount( counter - 1 )}>-1</button>
</div>
);
(2)useEffect
useEffect 相當于是 componentDidMount腹纳,componentDidUpdate 和 componentWillUnmount 這三個函數的組合,可以通過傳參及其他邏輯驱犹,分別模擬這三個生命周期函數嘲恍;
useEffect 第二個參數是一個數組,如果數組為空時雄驹,則只執(zhí)行一次(相當于componentDidMount)
如果數組中有值時佃牛,則該值更新時,useEffect 中的函數才會執(zhí)行 (相當于componentDidUpdate)
如果沒有第二個參數医舆,則每次render時俘侠,useEffect 中的函數都會執(zhí)行;
effect 中返回的函數(其清除函數)(頁面銷毀的時候調用)蔬将, (相當于componentWillUnmount)
如下代碼
const [counter,setCounter] = useState(0)
const [age,setAge] = useState(18)
useEffect(()=>{
document.title = counter
console.log('1')
return ()=>{
console.log('2')
}
},[counter])
useEffect(()=>{
console.log('3')
})
useEffect(()=>{
console.log('4')
},[counter,age])
useEffect(()=>{
console.log('5')
},[])
return (
<div>
<h2>當前計數:{counter}</h2>
<button onClick={e=>{setCounter(counter+1)}}>+1</button>
<button onClick={e=>{setAge(age+1)}}>+1</button>
</div>
);
(3) useContex
useContext() 狀態(tài)共享的函數鉤子
該鉤子的作用是爷速,在組件之間共享狀態(tài)。關于Context這里不再贅述霞怀,其作用就是可以做狀態(tài)的分發(fā)惫东,在React16.X以后支持,避免了react逐層通過Props傳遞數據毙石。
import React, {useState, useContext} from 'react';
function Test1() {
// hook : useState
// useState 本身是一個函數廉沮,來自react包
// const arr = useState(0)
// const state = arr[0]
// const setState = arr[1]
const [counter, setCount] = useState(0)
const AppContext = React.createContext({})
const A = () => {
const {name} = useContext(AppContext)
return (
<p>我是A組件的名字{name}</p>
)
}
const B = () => {
const {name} = useContext(AppContext)
return (
<p>我是B組件的名字{name}</p>
)
}
return (
<AppContext.Provider value={{name: 'hook測試'}}>
<h2>當前計數 {counter}</h2>
<button onClick={e => setCount(counter + 1)}>+1</button>
<button onClick={e => setCount(counter - 1)}>-1</button>
<A></A>
<B></B>
</AppContext.Provider>
);
}
export default Test1;
image.png