【React Hooks】memo和useCallback搭配所帶來的性能優化


前言

最近在用ts+hooks這些新特性開發新的項目,前沿的東西開發的感覺是很絲滑美妙的,時時刻刻都在踩坑,無法自拔。

問題描述

目錄結構大概是這樣的

--RtDetail
----Home
------index.scss
------index.tsx
----Search
------index.scss
------index.tsx
----Detail
------index.scss
------index.tsx

然后我在Home組件中引入了Search和Detail組件,偽代碼大概是這樣的

/** 
 * Home.tsx 偽代碼 
 * 大概就是引入了Search和Detail,給Search傳入一個回調,當Search的輸入框改變時候,觸發更改Home中的searchId
 */
...
let Home = () => {
    const [searchId, setSearchId] = useState(0)

    const handleSearchIdChange = (e) => {
         console.log('handleSearchChange 被創建了')
         setSearchId(e.target.value)
    }
    
    return (
        <>
            <Search handleSearchId={handleSearchId}/>
            <Detail />
        </>
    )
}

export default Home

/** Search.tsx 偽代碼 */
...
let Search = (props: ISearchProps) => {
    
    const { handleSearchId } = props

    return (
        <>
            <input onChange={(e) => {handleSearchId(e)}}/>
        </>
    )
}

export default Search
...

/** Detail.tsx */
...
let Detail = () => {

    console.log('Detail Component 被渲染了')
    return (
        <span>test</span>
    )
}

export default Detail
...

每次Search更改Home中seachId狀態的時候,導致以下2個問題:

  • 1.Detail都伴隨着被重新創建了,從而造成了不必要的性能浪費
  • 2.Home組件中,handleSearchId方法被重新創建

解決方案

memo+useCallback

對於問題1使用memo

/** 對Detail組件,包上一層memo,這是hooks提供的一個api */
...
let Detail = memo(() => {

    console.log('Detail Component 被渲染了')
    return (
        <span>test</span>
    )
})

export default Detail

React.memo類似於React.PureComponent,能對props做淺比較,防止組件無效的重復渲染!

對於問題2使用useCallback

/** 改寫Home.tsx */
...
let Home = () => {
    const [searchId, setSearchId] = useState(0)

    const handleSearchIdChange = (e) => {
         console.log('handleSearchChange 被創建了')
         setSearchId(e.target.value)
    }
    
    return (
        <>
            <Search handleSearchId={handleSearchId}/>
            <Detail />
        </>
    )
}

export default Home

useCallback用於緩存inline函數,防止因屬性更新時生成新的函數導致子組件重復渲染


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM