最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

react中常見hook的使用方式

 更新時(shí)間:2021年04月08日 09:23:43   作者:一顆冰淇淋  
這篇文章主要介紹了react中常見hook的使用方式與區(qū)別,幫助大家更好的理解和學(xué)習(xí)使用react,感興趣的朋友可以了解下

1、什么是hook?

react hook是react 16.8推出的方法,能夠讓函數(shù)式組件像類式組件一樣擁有state、ref、生命周期等屬性。

2、為什么要出現(xiàn)hook?

函數(shù)式組件是全局當(dāng)中一個(gè)普通函數(shù),在非嚴(yán)格模式下this指向window,但是react內(nèi)部開啟了嚴(yán)格模式,此時(shí)this指向undefined,無法像類式組件一樣使用state、ref,函數(shù)式組件定義的變量都是局部的,當(dāng)組件進(jìn)行更新時(shí)會重新定義,也無法存儲,所以在hook出現(xiàn)之前,函數(shù)式組件有很大的局限性,通常情況下都會使用類式組件來進(jìn)行代碼的編寫。

3、有哪些常用的hook?

(1) useState

使函數(shù)式組件也能保存狀態(tài)的一個(gè)hook,這個(gè)hook的入?yún)⑹菭顟B(tài)的初始值,返回值是一個(gè)數(shù)組,數(shù)組里第一個(gè)參數(shù)為狀態(tài)的值,第二個(gè)參數(shù)為修改狀態(tài)的方法。

// 初始化
const [ count,  setCount ] = useState(0)
// 更新
setCount(count+1)

(2) useEffect

函數(shù)式組件用來模擬生命周期的hook,可以模擬組件掛載完成、更新完成、即將卸載三個(gè)階段,即componentDidMount、componentDidUpdate、componentWillUnmount。

useEffect的一個(gè)參數(shù)為函數(shù),表示組件掛載、更新時(shí)執(zhí)行的內(nèi)容,在函數(shù)里再返回一個(gè)函數(shù),表示組件即將卸載時(shí)調(diào)用的函數(shù)。

第二個(gè)參數(shù)為可選項(xiàng),可傳入數(shù)組,數(shù)組里可以為空,表示不依賴任何狀態(tài)的變化,即只在組件即將掛載時(shí)執(zhí)行,后續(xù)任何狀態(tài)發(fā)生了變化,都不調(diào)用此hook。數(shù)組里也可以定義一或多個(gè)狀態(tài),表示每次該狀態(tài)變化時(shí),都會執(zhí)行此hook。

useEffect(()=>{
  // 這樣模擬的是 componentDidMount
}, [])

useEffect(()=>{
  // 這樣模擬的是componentDidMount 以及當(dāng)count發(fā)生變化時(shí)執(zhí)行componentDidUpdate
}, [count])

useEffect(()=>{
  return ()=>{
  // 這樣模擬的是 componentWillUnmount
  }
}, [])

(3) useContext

在沒有hook之前,我們通常都會通過 xxxContext.Provider 和 xxxContext.Consumer 的方式來傳遞和獲取context的值,使用hook之后,傳遞context的方式不變,但子元素獲取context的方式變得更加的簡潔。

// 以前的定義方式
const CountContext = React.createContext()
 <CountContext.Provider value={{ count: 10 }}>
     <...自定義的組件>
 </CountContext.Provider>

// 子元素
<CountContext.Consumer>
    { value => { console.log(value.count) }} //10
</CountContext.Consumer>

//使用context的獲取方式
const countObj = useContext(CountContext)
console.log(countObj.count) // 10

(4) useRef

useRef和類式組件中createRef用法比較類似,返回一個(gè)ref對象,這個(gè)對象在函數(shù)的整個(gè)生命周期都不變,根據(jù)這個(gè)特性,有兩種比較常見的用法。

① 用于dom元素或者組件上,通過current屬性可以獲取到dom元素或者類式組件的實(shí)例對象。需要注意的是,無論是useRef還是createRef或者是回調(diào)形式、字符串形式的ref,都是不能直接給函數(shù)式組件定義的,因?yàn)楹瘮?shù)式組件的this指向undefined,沒有實(shí)例對象,只能通過forwardRef定義到函數(shù)式組件中的某個(gè)dom元素。

// 這樣就將傳遞給函數(shù)式組件的ref綁定在了函數(shù)式組件內(nèi)部的input標(biāo)簽上
import React, { useRef, forwardRef } from 'react'

// 使用函數(shù)表達(dá)式的方式定義了一個(gè)函數(shù)式組件
const InputCom = forwardRef((props, ref) => {  
  return <input ref={ref}/> 
})

export default function refDemo(){
    const comRef = useRef()
    return(<div>
       <InputCom ref={comRef}/>     
    </div>) 
 }

② 保存一個(gè)數(shù)據(jù),該數(shù)據(jù)如果不手動修改,它在整個(gè)生命周期中都不變

const [ count, setCount ] = useState(0)
const prevCount = useState(count)
// 當(dāng)count發(fā)生變化時(shí),組件更新,對count的前一次數(shù)據(jù)進(jìn)行保存
useEffect(()=>{
  prevCount.current = count
}, [count])

(5) useReducer

useReducer相當(dāng)于是useState的升級版,作用與useState類似,都是用來保存狀態(tài),但它的不同點(diǎn)在于可以定義一個(gè)reducer的純函數(shù),來處理復(fù)雜數(shù)據(jù)。

// 定義一個(gè)處理數(shù)據(jù)的reducer純函數(shù)
function reducer(prevState, action){
  switch(action.type){
    case 'increment':
      return {...prevState, count: prevState.count + 1 }
    case 'decrement':
      return {...prevState, count: prevState.count - 1 }
    default:
      return prevState
  }
}

// 初始化狀態(tài)
const [ count, dispatch ] = useReducer(reducer, { count: 0 })
// 修改狀態(tài),此時(shí)的修改需要派發(fā)一個(gè)action,讓傳入的reducer函數(shù)進(jìn)行處理
dispatch({ type: 'increment' })

(6) useCallback

函數(shù)式組件中,每一次更新狀態(tài),自定義的函數(shù)都要進(jìn)行重新的聲明和定義,如果函數(shù)作為props傳遞給子組件,會造成子組件不必要的重新渲染,有時(shí)候子組件并沒有使用到父組件發(fā)生變化的狀態(tài),此時(shí)可以使用useCallback來進(jìn)行性能優(yōu)化,它會為函數(shù)返回一個(gè)記憶的值,如果依賴的狀態(tài)沒有發(fā)生變化,那么則不會重新創(chuàng)建該函數(shù),也就不會造成子組件不必要的重新渲染。

import React, { useState, useCallback, memo } from 'react'
const AddBtn = memo((props)=>{ // 使用函數(shù)表達(dá)式的方式定義了一個(gè)函數(shù)式組件
    return<button onClick={props.increment}>+1</button>
})

export default function CallBackPerformance(){
    const [ count, setCount ] = useState(0)
    const [ show, setShow ] = useState(true)
    const increment1 = () => {
        console.log('increment1被調(diào)用了')
        setCount(count+1)
    }

   const increment2 = useCallback(()=>{  // 使用了useCallback來優(yōu)化的函數(shù)
         console.log('increment2被調(diào)用了')
         setCount(count+1)
    },[count])

    return(<div>
            <div>當(dāng)前計(jì)數(shù):{count}</div>
            <AddBtn increment={increment1} name="1"/>
            <AddBtn increment={increment2} name="2"/>
            <button onClick={e => setShow(!show)}>切換show</button>
        </div>)
}
// 當(dāng)show這個(gè)狀態(tài)發(fā)生變化時(shí),子組件increment1會重新渲染,increment2不會重新渲染

(7) useMemo

useMemo也是返回一個(gè)記憶的值,如果依賴的內(nèi)容沒有發(fā)生改變的話,這個(gè)值也不會發(fā)生變化,useMemo與useCallback的不同點(diǎn)在于useMemo需要在傳入的函數(shù)里需要return 一個(gè)值,這個(gè)值可以是對象、函數(shù),格式如下。

useMemo(()=>{
   return { count }
}, [count])

// 使用useCallback時(shí)   
const increment2 = useCallback(()=>{
    setCount(count+1)
},[count])

// 使用useMemo模擬useCallback
const increment2 = useCallback(()=>{
    return ()=>{
        setCount(count+1)
    }
},[count])

// useMemo的應(yīng)用場景,當(dāng)要進(jìn)行一些復(fù)雜的計(jì)算時(shí),
//計(jì)算的值沒有發(fā)生變化,并不需要每一次更新都重新計(jì)算

import React, { useState, useMemo } from 'react'
const calculateNum = (count) => {
    console.log('total重新計(jì)算了')
    let total = 0
    for(let i = 0; i <= count; i++){
        total += i
    }
    return total
}

export default function ComplexUseMemo(){
    const [ count, setCount ] = useState(10)
    const [ show, setShow ] = useState(true)
    const total = useMemo(()=>{
        return calculateNum(count)
    }, [count])
    return(<div>
        <div>{total}</div>
        <button onClick={e=>setCount(count+1)}>+1</button>
        <button onClick={e=>setShow(!show)}>切換show</button>
    </div>)
}

(8) useImperativeHandle

這個(gè)是與forwardRef配合來使用的,當(dāng)我們對函數(shù)式組件使用forwardRef將ref指定了dom元素之后,那就父組件就可以任意的操作指定的dom元素,使用useImperativeHandle就是為了控制這樣的一種行為,指定父元素可操作的子元素的方法。

import React, {  useRef, useImperativeHandle, forwardRef } from 'react'
const InputComp = forwardRef((props, ref)=>{
  const childInputRef = useRef()
  useImperativeHandle(ref, ()=>({
    focus: ()=>{
      childInputRef.current.focus()
    }
  }), [childInputRef.current])

  return<input ref={childInputRef}></input>
})

export default function ImperativeHookDemo() {
  const inputRef = useRef()
  return(<div>
      <InputComp ref={inputRef}/>
      <button onClick={e=>inputRef.current.focus()}>聚焦</button>
    </div>)
}

(9) useLayoutEffect

這個(gè)方法與useEffect類似,只是執(zhí)行的順序稍有不同,useEffect是在組件渲染繪制到屏幕上之后,useLayoutEffect是render和繪制到屏幕之間。

4、如何自定義hook?

hook只能定義在函數(shù)式組件中,不能在普通函數(shù)中使用,如果我們想要使用到上面的hook來封裝一些方法供很多個(gè)組件調(diào)用,這時(shí)候就需要自定義hook,自定義hook的命名就是在函數(shù)名前加 use,函數(shù)名由 saveInfo 改為 useSaveInfo 即可。

以上就是react中常見hook的使用方式的詳細(xì)內(nèi)容,更多關(guān)于react hook的使用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用React?MUI庫實(shí)現(xiàn)用戶列表分頁功能

    使用React?MUI庫實(shí)現(xiàn)用戶列表分頁功能

    MUI是一款基于React的UI組件庫,可以方便地構(gòu)建美觀的用戶界面,使用MUI的DataTable組件和分頁器組件可以輕松實(shí)現(xiàn)用戶列表分頁功能,這篇文章使用MUI庫實(shí)現(xiàn)了用戶列表分頁功能,感興趣的同學(xué)可以參考下文
    2023-05-05
  • React利用lazy+Suspense實(shí)現(xiàn)路由懶加載

    React利用lazy+Suspense實(shí)現(xiàn)路由懶加載

    這篇文章主要為大家詳細(xì)介紹了React如何利用lazy+Suspense實(shí)現(xiàn)路由懶加載,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-06-06
  • react swiper@6.x 工作中遇到的問題處理方案

    react swiper@6.x 工作中遇到的問題處理方案

    本文總結(jié)了reactswiper@6.x版本的使用方法和配置,包括安裝步驟和配置自動輪播及移入停止的選項(xiàng),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • react 組件表格固定底部的實(shí)現(xiàn)代碼

    react 組件表格固定底部的實(shí)現(xiàn)代碼

    在React中,要實(shí)現(xiàn)一個(gè)組件表格并且固定底部,可以使用CSS的固定定位或絕對定位來實(shí)現(xiàn),下面通過示例代碼給大家分享react 組件表格固定底部的實(shí)現(xiàn)代碼,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • react使用useState修改對象或者數(shù)組的值無法改變視圖的問題

    react使用useState修改對象或者數(shù)組的值無法改變視圖的問題

    這篇文章主要介紹了react使用useState修改對象或者數(shù)組的值無法改變視圖的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 在React項(xiàng)目中添加吸頂效果的代碼示例

    在React項(xiàng)目中添加吸頂效果的代碼示例

    在大型Web應(yīng)用中,一個(gè)常見的設(shè)計(jì)需求是讓某些組件具有吸頂效果,這意味著當(dāng)頁面向下滾動時(shí),該組件會保持在屏幕頂部,在本文中,我們將介紹如何在React項(xiàng)目中實(shí)現(xiàn)吸頂效果。我們將首先討論使用原生JavaScript領(lǐng)域的方法來實(shí)現(xiàn),然后將這些方法與React結(jié)合起來
    2023-06-06
  • react如何實(shí)現(xiàn)篩選條件組件

    react如何實(shí)現(xiàn)篩選條件組件

    這篇文章主要介紹了react如何實(shí)現(xiàn)篩選條件組件問題,具有很好的參考價(jià)價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • react實(shí)現(xiàn)組件狀態(tài)緩存的示例代碼

    react實(shí)現(xiàn)組件狀態(tài)緩存的示例代碼

    本文主要介紹了react實(shí)現(xiàn)組件狀態(tài)緩存的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • ReactNative集成個(gè)推消息推送過程詳解

    ReactNative集成個(gè)推消息推送過程詳解

    這篇文章主要為大家介紹了ReactNative集成個(gè)推消息推送過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • React實(shí)現(xiàn)組件全屏化的操作方法

    React實(shí)現(xiàn)組件全屏化的操作方法

    開發(fā)今天給我提了一個(gè)sql編輯器輸入框比較小,不支持放大,不太方便,下面看下我的處理方法,本文基于React+antd,給大家演示一個(gè)完整的全屏demo,感興趣的朋友一起看看吧
    2021-10-10

最新評論

霍林郭勒市| 四川省| 肃南| 彰武县| 怀化市| 富源县| 无为县| 凌源市| 林芝县| 木兰县| 汕头市| 太仆寺旗| 饶河县| 吕梁市| 紫云| 纳雍县| 句容市| 萨嘎县| 兴文县| 永城市| 义乌市| 东城区| 新竹市| 蓬溪县| 滕州市| 临漳县| 子洲县| 兴仁县| 东光县| 甘肃省| 金沙县| 五寨县| 鹤壁市| 凤庆县| 驻马店市| 体育| 疏勒县| 搜索| 如东县| 合阳县| 明水县|