React memo減少重復(fù)渲染詳解
1. 概述
此方法是一個(gè) React 頂層 Api 方法,給函數(shù)組件來減少重復(fù)渲染,類似于 PureComponent 和 shouldComponentUpdate 方法的集合體。
React.memo頂層Api方法,它可以用來減少子組件的重復(fù)渲染次數(shù),從而提升組件渲染性能。
React.memo它是一個(gè)只能在函數(shù)組件中使用的頂層Api方法。
當(dāng)父組件發(fā)生改變時(shí),默認(rèn)情況下它的子孫組件也會(huì)重新渲染,當(dāng)某些子組件不需要更新時(shí),也會(huì)被強(qiáng)制更新,為了避免這種情況,我們可以使用 React.memo。
2. 使用
在不使用 React.memo 方法的情況下,子組件即使和父組件沒有任何關(guān)聯(lián),只要父組件更新,子組件也會(huì)跟著更新:
import React, { useState, memo } from 'react' const Child = () => { console.log('child') return ( <div> <h3>child組件</h3> </div> ) } const App = () => { let [count, setCount] = useState(100) let [name, setName] = useState('張三') return ( <div> <h3>App -- {count}</h3> <button onClick={() => { setCount(v => v + 1) }}> ++++ </button> <Child /> </div> ) } export default App
上面的方案對(duì)性能的消耗很大,于是我們使用 React.memo 方法來解決這個(gè)問題,我們可以這樣寫:
import React, { useState, memo } from 'react' const Child = memo(() => { console.log('child') return ( <div> <h3>child組件</h3> </div> ) }) const App = () => { let [count, setCount] = useState(100) let [name, setName] = useState('張三') return ( <div> <h3>App -- {count}</h3> <button onClick={() => { setCount(v => v + 1) }}> ++++ </button> <Child /> </div> ) } export default App
我們可以用一個(gè)更直觀的例子來展示 React.memo 的作用:
import React, { useState, memo } from 'react' // React.memo頂層Api方法,它可以用來減少子組件的重復(fù)渲染次數(shù),從而提升組件渲染性能 // React.memo它是一個(gè)只能在函數(shù)組件中使用的頂層Api方法 const Child = memo(({count}) => { console.log('child') return ( <div> {/* 此時(shí)子組件只依賴于父組件中的 count,所以父組件中的count改變, 子組件就會(huì)重新渲染,而input框中的值改變對(duì)子組件沒有影響 */} <h3>child組件 -- {count}</h3> </div> ) }) const App = () => { let [count, setCount] = useState(100) let [name, setName] = useState('張三') return ( <div> <h3>App -- {count}</h3> <input type="text" value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setCount(v => v + 1) }}> ++++ </button> <Child count={count} /> </div> ) } export default App
React.memo 中還可以寫回調(diào)函數(shù):
import React, { useState, memo } from 'react' // shouldComponentUpdate它必須要有一個(gè)返回值,true則表示繼續(xù)渲染,false停止渲染 // React.memo參數(shù)2返回值如果為true則表示停止渲染,false繼續(xù)渲染 const Child = memo( ({ count }) => { console.log('child') return ( <div> <h3>child組件 -- {count}</h3> </div> ) }, // prevProps 舊的props數(shù)據(jù) object // nextProps 新的props數(shù)組 object // 可以比較兩者的不同,來決定是否重新渲染 // 參數(shù)2寫的回調(diào)函數(shù),一般情況下都在props傳過來的數(shù)據(jù)為引用類型,才需要手動(dòng)來判斷,如果是基本類型則不需要寫參數(shù)2,來手動(dòng)判斷。 (prevProps, nextProps) => { // true/false // return false // console.log(prevProps, nextProps) return prevProps.count === nextProps.count } ) const App = () => { let [count, setCount] = useState(100) let [name, setName] = useState('張三') return ( <div> <h3>App -- {count}</h3> <input type="text" value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setCount(v => v + 1) }}> ++++ </button> <Child count={count} /> </div> ) } export default App
上文說到 React.memo 中參數(shù)2寫的回調(diào)函數(shù),一般情況下都在 props 傳過來的數(shù)據(jù)為引用類型,才需要手動(dòng)來判斷,如果是基本類型則不需要寫參數(shù)2,來手動(dòng)判斷。所以我們下面來看一個(gè)傳值為引用類型的例子:
import React, { useState, memo } from 'react' import _ from 'lodash' // shouldComponentUpdate它必須要有一個(gè)返回值,true則表示繼續(xù)渲染,false停止渲染 // React.memo參數(shù)2返回值如果為true則表示停止渲染,false繼續(xù)渲染 const Child = memo( ({ count }) => { console.log('child') return ( <div> <h3>child組件 -- {count.n}</h3> </div> ) }, // 使用lodash庫(kù)來完成對(duì)象的值的比較,從而用來完成減少組件的無(wú)用的重復(fù)渲染 (prevProps, nextProps) => _.isEqual(prevProps, nextProps) ) const App = () => { // let [count, setCount] = useState(100) let [count, setCount] = useState({ n: 100 }) let [name, setName] = useState('張三') return ( <div> {/* <h3>App -- {count}</h3> */} <h3>App -- {count.n}</h3> <input type="text" value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setCount({ n: Date.now() }) }} > ++++ </button> <Child count={count} /> </div> ) } export default App
注意:不使用參數(shù)2的時(shí)候,假設(shè)對(duì)象中屬性的值沒變,子組件在這種情況下也一定會(huì)重新渲染,這是因?yàn)閷?duì)象的引用地址變了。
到此這篇關(guān)于React memo減少重復(fù)渲染詳解的文章就介紹到這了,更多相關(guān)React memo內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Ant Design與Ant Design pro入門使用教程
Ant Design 是一個(gè)服務(wù)于企業(yè)級(jí)產(chǎn)品的設(shè)計(jì)體系,組件庫(kù)是它的 React 實(shí)現(xiàn),antd 被發(fā)布為一個(gè) npm 包方便開發(fā)者安裝并使用,這篇文章主要介紹了Ant Design與Ant Design pro入門,需要的朋友可以參考下2023-12-12Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例
這篇文章主要介紹了Next.js實(shí)現(xiàn)react服務(wù)器端渲染的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01利用React高階組件實(shí)現(xiàn)一個(gè)面包屑導(dǎo)航的示例
這篇文章主要介紹了利用React高階組件實(shí)現(xiàn)一個(gè)面包屑導(dǎo)航的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08react-router browserHistory刷新頁(yè)面404問題解決方法
本篇文章主要介紹了react-router browserHistory刷新頁(yè)面404問題解決方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-12-12React項(xiàng)目打包發(fā)布到Tomcat頁(yè)面空白問題及解決
這篇文章主要介紹了React項(xiàng)目打包發(fā)布到Tomcat頁(yè)面空白問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06