React?Hooks鉤子中API的使用示例分析
hooks是什么
hooks理解字面意思就是鉤子,是一些可以讓你在函數(shù)組件里鉤入 React state以及生命周期等特性的函數(shù),可以讓不編寫(xiě)class的情況下使用state以及其他的React特性
Hooks的作用
為函數(shù)組件提供狀態(tài),生命周期等原本在class組件中才提供的功能
Hooks只能在函數(shù)組件中使用
可以理解為通過(guò)Hooks為函數(shù)組件鉤入class組件的特性
使用Hooks組件前后開(kāi)發(fā)模式的對(duì)比
使用前(React v 16.8前):class組件(提供狀態(tài))+函數(shù)組件(展示內(nèi)容)
使用后(React v 16.8后):Hooks(提供狀態(tài))+函數(shù)組件(展示內(nèi)容)
Hooks使用策略
(1)react沒(méi)有計(jì)劃從React中移除class
(2)hook和現(xiàn)有代碼可以同時(shí)工作,可以漸進(jìn)式使用
不推薦直接使用Hooks大規(guī)模重構(gòu)現(xiàn)有組件
推薦新功能使用Hooks,復(fù)雜功能實(shí)現(xiàn)不來(lái),也可以繼續(xù)使用class
(3)class組件相關(guān)的API在hooks里面可以不用
state setState 鉤子函數(shù),this相關(guān)用法
(4)原來(lái)學(xué)習(xí)的內(nèi)容還是要用
JSX:{} onClick={} 、條件渲染、列表渲染、樣式處理
組件:函數(shù)組件,組件通訊
react開(kāi)發(fā)理念:?jiǎn)蜗驍?shù)據(jù)流,狀態(tài)提升
為什么要有Hooks
首先我們要了解react的本質(zhì),接著從函數(shù)組件和類(lèi)組件進(jìn)行分析優(yōu)缺點(diǎn)
react本質(zhì):用于構(gòu)建用戶界面的javascript庫(kù),是對(duì)特定功能的封裝,主要對(duì)url進(jìn)行拆分
react組件的模型其實(shí)很直觀,就是從model到view的映射,這里的model對(duì)應(yīng)的是react的state和props
函數(shù)式組件的好處:
- 函數(shù)本身比較簡(jiǎn)單,更好的勝任根據(jù)狀態(tài)來(lái)渲染url這件事
- hooks讓函數(shù)組件內(nèi)部有了維護(hù)狀態(tài)的能力
- hooks帶來(lái)了組件的邏輯復(fù)用的能力
class組件自身的問(wèn)題:
- 在根據(jù)狀態(tài)來(lái)渲染url這件事上,class組件并沒(méi)有發(fā)揮它的重要功能
- 組件之間很少繼承
- 組件之間很少相互訪問(wèn)
useState
作用:為函數(shù)組件提供state狀態(tài)
步驟:
- 導(dǎo)入useState函數(shù)
- 調(diào)用useState函數(shù),傳入初始值,返回狀態(tài)和修改狀態(tài)的函數(shù)
- 使用:在jsx中展示狀態(tài),特定的時(shí)機(jī)調(diào)用修改狀態(tài)的函數(shù)修改狀態(tài)
- 定義state數(shù)據(jù),返回一個(gè)數(shù)組,有兩個(gè)值,第一個(gè)值,定義數(shù)據(jù)初始化的值,第二個(gè)值,修改數(shù)據(jù)函數(shù),可以做到頁(yè)面的響應(yīng)式
useState兩種格式:
格式1:傳入值 useState(0) 或useState('abc')
格式2:傳入回調(diào),useState({上一次的值}=>{return 新值})
- 回調(diào)函數(shù)的返回值就是狀態(tài)的當(dāng)前值
- 回調(diào)函數(shù)只會(huì)觸發(fā)一次
代碼展示
import React, { useState } from 'react' export default function UseState() { let [count,setCount]=useState(10) // 他是異步的操作,在頁(yè)面數(shù)據(jù)會(huì)進(jìn)行更新,但是下面打印的數(shù)據(jù)是沒(méi)有更新,原因是因?yàn)樗钱惒降? const plus=()=>{ setCount(count+5) } return ( <div> {/* 函數(shù)組件中沒(méi)有this指向,我們可以直接調(diào)用 */} <div>{count}</div> <button onClick={()=>setCount(count++)}>加加</button> <button onClick={plus}>plus</button> </div> ) }
注意:上面必須引入useState 使用
useEffect使用
函數(shù)式組件:
主作用:就是根據(jù)數(shù)據(jù)(state/props)渲染ul
副作用:數(shù)據(jù)請(qǐng)求,手動(dòng)修改DOM、開(kāi)啟定時(shí)器、清空定時(shí)器、localStorage操作等
副作用:只要是渲染數(shù)據(jù)之外的操作都是副作用,副作用不一定非要寫(xiě)在useEffect里,可以寫(xiě)外面,但是寫(xiě)useEffect會(huì)起到約束作用
執(zhí)行時(shí)機(jī)(以下兩種情況會(huì)執(zhí)行Effect):
- 組件掛載時(shí),執(zhí)行一次(相當(dāng)于生命周期中componentDidMount)
- 組件更新時(shí),可能執(zhí)行多次(相當(dāng)于生命周期中的componentDidUpdate)
在實(shí)際開(kāi)發(fā)中,副作用是不可避免的,react專(zhuān)門(mén)用useEffect來(lái)處理組件中的副作用
useEffect依賴項(xiàng)
有兩個(gè)參數(shù):(參數(shù)一:(副作用函數(shù)),參數(shù)二:(執(zhí)行副作用函數(shù)的依賴項(xiàng),他決定了什么時(shí)候執(zhí)行參數(shù)1(副作用)))
- 如果不設(shè)置第二個(gè)參數(shù),那么每次頁(yè)面更新他都會(huì)執(zhí)行
- 參數(shù)是空數(shù)組,永遠(yuǎn)只執(zhí)行第一次
- 指定依賴項(xiàng),執(zhí)行時(shí)機(jī)(初始化執(zhí)行一次,依賴項(xiàng)發(fā)生變化執(zhí)行一次)可以有多個(gè)依賴項(xiàng)
- useEffect() 代替三個(gè)生命周期函數(shù) componentDidMount compoentDidUpdate 鉤子函數(shù), componentWillUnmount 生命周期
使用情景
- 事件綁定
- 發(fā)送請(qǐng)求獲取數(shù)據(jù)等 axios ajax
useEffect(()=>{ 邏輯}) 頁(yè)面數(shù)據(jù)只要更新就會(huì)觸發(fā)useEffect() useEffect(()=>{},[]) useEffect() 只執(zhí)行一次,只有頁(yè)面第一次加載的時(shí)候觸發(fā),componentDidMount useEffect(()=>{}, [num,count]) 監(jiān)聽(tīng)數(shù)據(jù)改變執(zhí)行,num和count發(fā)生變化的時(shí)候觸發(fā)。compoentDidUpdate useEffect(()=>{ return ()=>{ console.log("相當(dāng)于compoentDidUnmount") } },[]) //回調(diào)函數(shù)返回函數(shù),返回的函數(shù)相當(dāng)于銷(xiāo)毀生命周期函數(shù)。
useMemo使用
相當(dāng)于vue中計(jì)算屬性,他一般需要返回一個(gè)結(jié)果,具有緩存性的效果
useMemo他是在DOM更新的時(shí)候觸發(fā)的,useEffect() DOM更新后觸發(fā)的副作用函數(shù)
緩存復(fù)雜運(yùn)算的結(jié)果,避免重復(fù)調(diào)用執(zhí)行
useMemo頁(yè)面一般會(huì)渲染第一次執(zhí)行后的結(jié)果
代碼展示
import React, { useMemo, useState } from 'react' export default function UseState() { let [count,setCount]=useState(10) // useMemo必須有返回值,而且他是在dom更新發(fā)生變化,比useEffect執(zhí)行的快,useEffect是dom更新完才執(zhí)行的,監(jiān)聽(tīng)count值變化 const double=useMemo(()=>{ console.log('useMemo觸發(fā)'); return count+6 },[count]) return ( <div> {/* 函數(shù)組件中沒(méi)有this指向,我們可以直接調(diào)用 */} <div>{count} {double}</div> <button onClick={()=>setCount(count*2)}>count二倍</button> </div> ) }
useMemo緩存組件方式
第一種通過(guò)useMemo緩存組件
//useMemoe緩存組件 function Home() { let [count,setcount] = useState(10) let [num,setnum] = useState(20) //通過(guò)useMemoe對(duì)組件進(jìn)行緩存,避免父組件中根子組件無(wú)關(guān)數(shù)據(jù)更新導(dǎo)致子組件的重新渲染。 let theme = useMemo(()=>{ return ( <Theme count={count}></Theme> ) },[count]) return ( <div> <h3 >count--{count}</h3> <button onClick={()=>setcount(count+1)}>count++</button> <h3 >num--{num}</h3> <button onClick={()=>setnum(num+1)}>num++</button> <hr /> {theme} </div> ) } function Theme(props){ useEffect(()=>{ console.log("子組件渲染") }); return ( <h3>子組件接受數(shù)據(jù){props.count}</h3> ) }
第二種通過(guò)react自帶的memo方法
memo是一個(gè)高階組件方法,接受一個(gè)組件作為參數(shù),根據(jù)組件傳遞的參數(shù)值,對(duì)組件進(jìn)行緩存,避免組件的多余的DOM渲染效果
function Home() { let [count,setcount] = useState(10) let [num,setnum] = useState(20) return ( <div> <h3 >count--{count}</h3> <button onClick={()=>setcount(count+1)}>count++</button> <h3 >num--{num}</h3> <button onClick={()=>setnum(num+1)}>num++</button> <hr /> <Theme count={count}></Theme> </div> ) } //通過(guò)memo對(duì)組件進(jìn)行緩存,避免父組件中根子組件無(wú)關(guān)數(shù)據(jù)更新導(dǎo)致子組件的重新渲染。 const Theme = memo((props)=>{ useEffect(()=>{ console.log("子組件渲染") }); return ( <h3>子組件接受數(shù)據(jù){props.count}</h3> ) })
useMemo和useEffect的區(qū)別
不同點(diǎn):
useEffect是在dom更新后觸發(fā)的副作用函數(shù),他被稱(chēng)為副作用函數(shù)就是因?yàn)樗谖覀兏峦瓿芍蟛磐ㄖ覀儯?lèi)似于馬后炮,useEffect不需要返回值,他沒(méi)有數(shù)據(jù)緩存的作用
useMemo是在dom更新時(shí)觸發(fā)的,useMemo必須要返回?cái)?shù)據(jù)的結(jié)果,他是具有緩存數(shù)據(jù)的作用
共同點(diǎn):
如果非要說(shuō)共同點(diǎn),那么他倆都有兩個(gè)參數(shù),并且第二個(gè)參數(shù)如果是空[]的話,那么他的數(shù)據(jù)只會(huì)執(zhí)行一次,也可以給他設(shè)置監(jiān)聽(tīng)項(xiàng),[監(jiān)聽(tīng)值的名稱(chēng)],第二個(gè)參數(shù)是可選參數(shù),也可以不寫(xiě),不寫(xiě)就是頁(yè)面只要發(fā)生一點(diǎn)改變,就會(huì)重新渲染一次,浪費(fèi)數(shù)據(jù)更新的性能
useCallback使用
在上述的例子中如果我們傳遞的是普通的變量,緩存后,父組件更新的話不會(huì)導(dǎo)致子組件的更新,但是如果你傳遞的是一個(gè)函數(shù),父組件的每次更新都會(huì)重新調(diào)用一次函數(shù),這個(gè)時(shí)候就會(huì)不同函數(shù)調(diào)用,會(huì)導(dǎo)致子組件的重新渲染,如果我們還要做組件緩存,我們可以使用useCallback() , 可以對(duì)函數(shù)進(jìn)行一個(gè)緩存的作用
代碼展示
function Home() { let [count,setcount] = useState(10) let [num,setnum] = useState(20) const handlerCount = ()=>{ console.log(count); } const callback = useCallback(()=>{ handlerCount(); },[count]); return ( <div> <h3 >count--{count}</h3> <button onClick={()=>setcount(count+1)}>count++</button> <h3 >num--{num}</h3> <button onClick={()=>setnum(num+1)}>num++</button> <hr /> <Theme count={count} handle={callback}></Theme> </div> ) } //通過(guò)memo對(duì)組件進(jìn)行緩存,避免父組件中根子組件無(wú)關(guān)數(shù)據(jù)更新導(dǎo)致子組件的重新渲染。 const Theme = memo((props)=>{ useEffect(()=>{ console.log("子組件渲染") }); return ( <div> <h3>子組件接受數(shù)據(jù){props.count}</h3> <button onClick={()=>props.handle()}>點(diǎn)擊</button> </div> ) })
useMemo,memo,useCallback如何提升性能的(面試題必問(wèn))?
useMemo主要的作用是緩存復(fù)雜運(yùn)算的數(shù)據(jù)返回的結(jié)果,有兩個(gè)參數(shù),第二個(gè)參數(shù)可以定義要監(jiān)聽(tīng)的數(shù)據(jù),并且需要返回,跟useEffect第二個(gè)參數(shù)的作用類(lèi)同
當(dāng)父組件的組件更新的時(shí)候會(huì)導(dǎo)致子組件的重新渲染,但是如果父組件的更新的數(shù)據(jù)沒(méi)有傳遞給子組件的話,這時(shí)候還讓子組件重新渲染的話,會(huì)導(dǎo)致組件更新性能消耗比較大
所以說(shuō)這個(gè)時(shí)候我們可以使用useMemo,或者使用react內(nèi)置的memo方法對(duì)子組件進(jìn)行緩存,這樣只有父組件更新跟子組件有關(guān)的數(shù)據(jù)時(shí)才會(huì)導(dǎo)致子組件重新渲染,從而提高組件的渲染性能
但是如果我們給子組件傳遞的是一個(gè)方法的時(shí)候,上面的useMemo,memo方法緩存就不起作用了,原因是父組件每更新一次會(huì)導(dǎo)致方法的重新調(diào)用,進(jìn)而導(dǎo)致子組件的重新更新,這時(shí)候我們可以用到useCallback對(duì)傳遞的方法進(jìn)行緩存,監(jiān)聽(tīng)數(shù)據(jù)更新后才會(huì)重新調(diào)用方法,從而提高組件的渲染性能
useContext使用
用來(lái)獲取context狀態(tài)樹(shù)的內(nèi)容數(shù)據(jù)的Hooks的APi,相當(dāng)于class組件中static contextType = react.createContext創(chuàng)建的對(duì)象內(nèi)容
代碼展示
import React, { useContext, useState } from 'react'; //useContext用于獲取context狀態(tài)樹(shù)的值 // 首先創(chuàng)建一個(gè)空的context對(duì)象 const ThemContext =React.createContext(); function UseState() { let [color,setColor]=useState('#ff0000') return ( <div> {/* 通過(guò)Provider傳過(guò)來(lái)一個(gè)value值,是一個(gè)對(duì)象 */} <ThemContext.Provider value={{color:color}}> <button onClick={()=>setColor('pink')}>粉色</button> <button onClick={()=>setColor('blue')}>藍(lán)色</button> <button onClick={()=>setColor('green')}>綠色</button> <Son></Son> </ThemContext.Provider> </div> ) } // 子組件 function Son(props) { // 通過(guò)useContext獲取父組件傳過(guò)來(lái)的值 const context=useContext(ThemContext) return ( <div> {/* 然后對(duì)他進(jìn)行樣式綁定 */} <h3 style={context}>hello,react</h3> </div> ) } export default UseState
useRef使用
useRef 作用相當(dāng)于class組件React.createRef()的作用,用于創(chuàng)建ref節(jié)點(diǎn)對(duì)象的內(nèi)容
//創(chuàng)建一個(gè)ref對(duì)象的內(nèi)容 let inp = useRef(null); const setVal =()=>{ console.log(inp.current.value); } <input placeholder='輸入內(nèi)容' ref={inp} onChange={setVal}/>
為什么在函數(shù)組件中無(wú)法使用ref
普通的類(lèi)組件有實(shí)例所以可以用React。createRef()掛載到節(jié)點(diǎn)或者組件上,然后通過(guò)this獲取到該節(jié)點(diǎn)或組件,正常情況下ref是不能掛到函數(shù)組件上,因?yàn)楹瘮?shù)組件沒(méi)有實(shí)例
如何在類(lèi)組件中使用ref屬性
我們可以通過(guò)forwardRef將ref父類(lèi)的ref作為參數(shù)傳入函數(shù)式組件中
forwardRef是一個(gè)高階函數(shù),跟memo一樣
還有一種方法就是把函數(shù)組件改成類(lèi)組件
function Home() { //定義一個(gè)初始化變量 let inpRef = useRef(null); const getTheme = ()=>{ console.log(inpRef); } return ( <div> <input placeholder='輸入內(nèi)容'/> <button onClick={getTheme}>獲取子組件對(duì)象</button> <hr /> <Theme ref={inpRef}/> </div> ) } const Theme = forwardRef(function(props,ref){ return ( <h3 ref={ref}>文字內(nèi)容顯示</h3> ) })
自定義hooks
寫(xiě)一個(gè)自定義頁(yè)面標(biāo)題的效果,路由中使用
import { useEffect } from "react"; //自定義顯示標(biāo)題的Hooks的方法內(nèi)容 const useTitle = (title) => { useEffect(() => { document.title = title; return ()=>{ document.title="React 頁(yè)面" } }, []); return; } export { useTitle };
import { useTitle } from "../context/hooksApi" export default function My(){ useTitle("個(gè)人中心") return ( <div> <h3>個(gè)人中心</h3> </div> ) }
還有其他的自定義hooks API方法,這舉例的是一種
到此這篇關(guān)于React Hooks鉤子中API的使用示例分析I的文章就介紹到這了,更多相關(guān)React Hooks API內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在React中用canvas對(duì)圖片標(biāo)注的實(shí)現(xiàn)
本文主要介紹了在React中用canvas對(duì)圖片標(biāo)注的實(shí)現(xiàn) ,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05React項(xiàng)目build打包頁(yè)面空白的解決方案
React項(xiàng)目執(zhí)行build命令后,在本地服務(wù)器打開(kāi)頁(yè)面是空白的,本文主要介紹了React項(xiàng)目build打包頁(yè)面空白的解決方案,感興趣的可以了解一下2023-08-08React實(shí)現(xiàn)下拉框的key,value的值同時(shí)傳送
這篇文章主要介紹了React實(shí)現(xiàn)下拉框的key,value的值同時(shí)傳送方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08