1. 前言
what Hook
Hook
是React 16.8
的新增特性蔑赘。它可以讓你在不編寫class組件
的情況下使用state
以及其他的React
特性镀脂。
2. why
之前的組件形式缺點(diǎn)
- 函數(shù)組件一般是無狀態(tài)組件
- 類組件可以有狀態(tài),也可以無狀態(tài)
- 組件之間
復(fù)用
狀態(tài)邏輯很難
,組件維護(hù)
越來越復(fù)雜
class組件
中的this
難以理解
3. Hook 基本概念
現(xiàn)在的函數(shù)組件也可以是有狀態(tài)的組件殴俱,內(nèi)部也可以維護(hù)自身的狀態(tài)以及做一些邏輯方面的處理
- 避免地獄式嵌套,可讀性提高
- 函數(shù)式組件,比
class組件
更容易理解- UI和邏輯更容易分離
- 基本不需要
this
4. 引入hook之前的代碼問題
簡(jiǎn)單的計(jì)數(shù)器案例
function MyCom(){
let count = 0
function add(){
count ++
console.log(count)
}
return (
<div>
{count}
<button onClick={add}>點(diǎn)我</button>
</div>
)
}
ReactDOM.render(
<MyCom/>,
document.getElementById("app")
)
點(diǎn)擊按鈕界面變量不跟著變
5. Hooks 有哪些常用的API
Hooks
讓我們的函數(shù)組件擁有了類組件的特性,例如組件內(nèi)的狀態(tài)主籍、生命周期
1.useState 組件內(nèi)的狀態(tài)
2.useEffect 生命周期
3.其他
6. 語法-State
const [state,setState] = useState(initialState)
1.
state
為變量
2.initialState state
變量的初始值
3.
setState
修改state
值的方法
4.setState
異步執(zhí)行
7.hook -useState
包含--基本類型寫法
包含--引用類型寫法
function MyCom(){
// 聲明一個(gè)叫 count 的state變量, 初始值為0
let [count, setCount] = React.useState(0)
// 聲明一個(gè) 叫obj的 state變量 初始值為空對(duì)象
let [obj, setObj] = React.useState({})
function add(){
// 基本類型的修改
setCount(++count)
// 引用類型的修改
setObj({
name: 'a'+count
})
console.log(count)
}
return (
<div>
{count}-{obj.name}
<button onClick={add}>點(diǎn)我</button>
</div>
)
}
在函數(shù)組件中通過
useState
實(shí)現(xiàn)函數(shù)內(nèi)部維護(hù)state
鲤嫡,參數(shù)為state
默認(rèn)的值,返回值是一個(gè)數(shù)組柿祈,
第一個(gè)值為當(dāng)前的state
哈误,
第二個(gè)值為更新state
的函數(shù)
8 類組件 VS 函數(shù)式組件
1.
state
聲明方式:
在函數(shù)組件中通過useState
直接獲取,類組件通過constructor
構(gòu)造函數(shù)中設(shè)置
2.
state
讀取方式:
在函數(shù)組件中直接使用變量
躏嚎,類組件通過this.state.count
的方式獲取
3.
state
更新方式:
在函數(shù)組件中通過setCount
更新蜜自,類組件通過this.setState()
總結(jié)就是
useState
使用起來更為簡(jiǎn)潔
,減少了this
指向不明確的情況
9. hook-鉤子 -useEffect
9.1語法
React.useEffect
(參數(shù)1,參數(shù)2)
參數(shù)1 是回調(diào)函數(shù)
參數(shù)2 是參數(shù)1 這個(gè)函數(shù)監(jiān)聽的變量
9.2 useEffect 相當(dāng)于3個(gè)鉤子的綜合
1.componentDidMount
2.componentDidUpdate
3.componentWillUnMount
9.3 分析
參數(shù)2 為空 不寫: DidMount+DidUpdate
在第一次渲染和更新之后都會(huì)執(zhí)行
參數(shù)2 空數(shù)組[] ,DidMount
第一次渲染后
參數(shù)2 [變量], 監(jiān)聽變量的改變 componentDidUpdate
React
將對(duì)前一次渲染的變量值count
和后一次渲染的count
值進(jìn)行比較
9.4 代碼
function MyCom(){
let [count, setCount] = React.useState(0)
let [obj, setObj] = React.useState({})
function add(){
// setCount(++count)
setObj({
name: 'a'+count
})
console.log(count)
}
React.useEffect(() => {
console.log("初始化或更新1")
})
React.useEffect(() => {
console.log("初始化2")
}, [])
React.useEffect(() => {
console.log("初始化或count更新3")
}, [count,obj])
return (
<div>
{count}-{obj.name}
<button onClick={add}>點(diǎn)我</button>
</div>
)
}
這個(gè)建議 還是自己寫寫,因?yàn)榇a本身也很簡(jiǎn)單
10. 清除函數(shù)
回調(diào)函數(shù)中可以返回一個(gè)清除函數(shù)卢佣,這是
effect
可選的清除機(jī)制重荠,相當(dāng)于類組件中componentwillUnmount
生命周期函數(shù),可做一些清除副作用的操作,比如定時(shí)器
// 創(chuàng)建響應(yīng)數(shù)據(jù)以及修改方法
let [num,setNum]=useState(20);
// 會(huì)在更新之前 執(zhí)行指定的銷毀函數(shù)
// 防止初始化的代碼 重復(fù)綁定 定時(shí)器
useEffect(()=>{
console.log("useEffect")
// 綁定定時(shí)器 讓num遞增
let timer=setInterval(()=>{
console.log("定時(shí)器");
num++;
setNum(num);//num發(fā)生變化
},1000);
return ()=>{//銷毀
clearInterval(timer);
}
})
11. 總結(jié)
1.每調(diào)用
useHook
一次都會(huì)生成一份獨(dú)立的狀態(tài)
2.通過自定義hook
能夠更好的封裝我們的功能
3.useEffect
相當(dāng)于componentDidMount珠漂,componentDidUpdate 和 componentWillUnmount
這三個(gè)生命周期函數(shù)的組合
12.其他hooks
useReducer
useCallback
useMemo
useRef
13. 這里再梳理個(gè) useReducer
其實(shí)就是 useState的替代版 主要用來 結(jié)合
redux
中的reducer
13.1 簡(jiǎn)單的看下 store 中 redux的結(jié)構(gòu)
import { createStore } from "redux";
let defaultState = {
counter:0
}
export const reducer = (state=defaultState,{type,payload=10})=>{
switch (type){
case "counter/incremented":{
let tempState = JSON.parse(JSON.stringify(state));
tempState.counter += payload
return tempState
}
case "counter/decremented":{
return{
...state,
counter:state.counter - payload
}
}
default:{
console.log("switch 默認(rèn)")
return state
}
}
}
let store = createStore(reducer)
export default store
13.2 使用 useReducer
import { useState, useEffect ,useReducer} from 'react';
import {reducer} from "../store"
function HookPage() {
const [state, dispatch] = useReducer(reducer, {counter:99})
}
return (
<div className="App">
<h1>{state.counter}</h1>
<button onClick={()=>{
dispatch({type:"counter/decremented",payload:100})
}}> redux</button>
</div>
);
}
export default HookPage;
13.3 分析
useReducer()
參數(shù)1: 就是reducer
參數(shù)2:就是初始值
參數(shù)3:是個(gè)初始化的回調(diào)函數(shù)
14. 完整的 組件內(nèi)使用 hook
import { useState, useEffect ,useReducer} from 'react';
import {reducer} from "../store"
function HookPage() {
let [counter, setCounter] = useState(0)
let [person, setPerson] = useState({ name: "yzs" })
const [state, dispatch] = useReducer(reducer, {counter:99})
function increase(v) {
counter += v
setCounter(counter)
}
function update() {
setPerson({
name: "鄭州"
})
}
// **************鉤子
useEffect(() => {
console.log("初始化或者更新")
})
useEffect(() => {
console.log("[] 初始化")
},[])
useEffect(() => {
console.log("初始化或 對(duì)應(yīng)的值變化")
},[counter,person])
return (
<div className="App">
<h1>{counter}</h1>
<button onClick={() => {
increase(10)
}}>增加</button>
<hr />
<h1>{person.name}</h1>
<button onClick={update}> name</button>
<hr/>
<h1>{state.counter}</h1>
<button onClick={()=>{
dispatch({type:"counter/decremented",payload:100})
}}> redux</button>
</div>
);
}
export default HookPage;
15. 總結(jié)性hook
可參考這篇文章 react常用-hook總結(jié)