1樓:龍背上的騎兵
使用自定義compare函式.
其實題主的意思就是實現shouldComponentUpdate的方法,可以精確控制哪些prop才能導致重繪。
這個功能很容易想到React.memo , 預設情況下 React.memo 會使用props的shadowEqual來對比,滿足大部分場景。
但是例如defaultValue這種非受控屬性當它變化時沒必要去重繪元件, 所以就需要手動定製比較函式。使用React.memo(Component, compare)即可實現。
和shouldComponentUpdate不同的是,compare為 true表示是相同屬性,不重繪,反之才重繪,和`shouldComponentUpdate`剛好相反。
function
Input
()function
isSameInput
(props
,newProps
)export
default
React
.memo
(Input
,isSameInput);
2樓:伊撒爾
很多方法
現成的,使用 memo,對元件進行包裹,這樣 props 就會進行淺比較
const component = memo(Component)
hooks 中的 useMemo 可以用來快取函式
const component = useMemo(() => , [props.a])
這兩個是有區別的,前者是props 的淺比較,比較看看要不要clone子元素,後者是比較props,然後快取這個函式,然後根據 props 變化,對比這兩個元件
我認為後者更好,因為這種比較是相對比較嚴格的,更安全可靠
當然還有一點很重要,memo 是針對元件的快取,但是實際上,需要快取的不只是元件,jsx 的任何一部分都可以被快取,所以 useMemo 更加通用而且符合語義
其實這裡有乙個很遠古的問題。說到底是 h 函式的問題
因為 render 都會重新 h 一堆 jsx,導致每次生成的都是新的,後來大家發現,這樣效能並不好,於是就有人反其道而為之
其中比較徹底的是 vue3,它做了一下幾件事情
將靜態的 jsx 元素全域性提公升,保證只 h 一次(相當於自動 useMemo)
將一些 handler 進行快取,保證這些函式只生成一次(相當於自動 useCallback)
內建 props 的淺比較(相當於自動 memo)
做了這一堆,其實就是快取 jsx,讓他們能夠進行比較,無論是淺比較還是嚴格相等
這樣做的好處是,大部分 case 是可以提公升效能而且符合中國人思維的
那為什麼 react 和 jsx 外掛程式不做這些事情呢?其實真的一直很迷
這是 dan 給的回覆:React.memo() by gaearon · Pull Request #63 · reactjs/rfcs
他認為淺比較不靠譜而且每個元件都去遍歷 props 的效能也不好
我還問過別人,還有人說向後相容,為了相容過去眾多 react 元件
當然其實不內建也沒有關係,這樣依賴,就全靠使用者的編碼能力了,使用者一定要有對 jsx 進行 memo 的概念,這樣一樣可以寫出非常精確的效能
然後就是關於 fre,我會在 fre2 中移除 memo,因為基於 memo 的這種 props 的淺比較不如 useMmemo 的陣列比較更可靠,不過為了找到一種權衡,fre 可能會這樣:
如果能夠嚴格相等 === ,那麼 fre 就會盡可能在框架內部處理如果是淺比較/陣列依賴的比較,這種比較通常來說是不可靠的,不應該由框架內建
什麼情況下可以嚴格對等呢?那就是你利用 memo 去快取引用的時候
所以 reactor 一定要有 memo 的概念了
3樓:
當Parent re-render時,Child也會re-render,除非以下2種情況之一發生:
父元件渲染的JSX tree中,在某個位置使用的物件(react element,即React.createElement()返回的物件)與上次渲染時相同(在同乙個位置使用同乙個物件引用),這時Child元件不會re-render。
Child元件被React.memo裝飾,並且傳給Child元件的props與上次渲染相同。
這種情況可以理解為React.memo幫我們快取了上次渲染時使用的jsx element物件。即:
const Component = React.memo(() =>
})等價於
const Component = () =>
count]) // deps陣列包含所有Parent可能傳入的props value
}demo:
white-currying-c94hn - CodeSandbox
詳細解釋見我的React效能優化總結:
【React效能優化總結】React元件什麼時候重新渲染?如何做效能優化? - csRyan的學習專欄 - SegmentFault 思否
4樓:verySao
類元件中我們通過 shouldComponentUpdate 生命週期或繼承 React.PureComponent 來控制項是否重新渲染。
在函式元件中,可以通過 React.memo 或 React.useMemo 來實現相同的功能:
import
React
,from
"react"
;export
const
MemoComponent
=React
.memo
(props
=>