Component與PureComponent對(duì)比解析
題外話
有啥不對(duì)的請(qǐng)多多指教,研究的不算很深,記錄為了分享,也為了博采眾長(zhǎng),完善知識(shí)。
官方文檔
React.PureComponent
與 React.Component
很相似。兩者的區(qū)別在于 React.Component
并未實(shí)現(xiàn) shouldComponentUpdate()
,而 React.PureComponent
中以淺層對(duì)比 prop 和 state 的方式來實(shí)現(xiàn)了該函數(shù)。
官方解釋也很容易理解,React.PureComponent
比React.Component
中多實(shí)現(xiàn)了一個(gè)方法,就導(dǎo)致了在組件數(shù)據(jù)發(fā)生變化時(shí),React.PureComponent
會(huì)先進(jìn)行和上一次的比較,如果相同,就不會(huì)再繼續(xù)更新了。
口說無憑,還是得通過代碼來體會(huì)。
對(duì)比
先看兩者相同得地方 代碼如下
class Box1 extends React.Component { render() { console.log('Box1 update'); return <div>Box1: {this.props.count}</div>; } }
class Box2 extends React.PureComponent { render() { console.log('Box2 update'); return <div>Box2: {this.props.count}</div>; } }
先制作2個(gè)對(duì)比的組件Box1與Box2, 然后制作一個(gè)父組件引入其中,并設(shè)置一個(gè)方法
export default () => { const [count, setCount] = React.useState(1); console.log('parent update'); return ( <div> <Box1 count={count}/> <Box2 count={count}/> <button onClick={() => setCount(count + 1)}>+1</button> </div> ); };
此時(shí),點(diǎn)擊button按鈕的時(shí)候,上述2個(gè)Box組件都會(huì)進(jìn)行更新。
這也是最基礎(chǔ)的組件更新。
取消外部數(shù)據(jù)引入
class Box1 extends React.Component { render() { console.log('Box1 update'); return <div>Box1</div>; } } class Box2 extends React.PureComponent { render() { console.log('Box2 update'); return <div>Box2</div>; } } export default () => { const [count, setCount] = React.useState(1); console.log('parent update'); return ( <div> <Box1 /> <Box2 /> <button onClick={() => setCount(count + 1)}>+1</button> </div> ); };
取消Box組件內(nèi)對(duì)外部count的引入
此時(shí)頁面更新為
此時(shí)會(huì)發(fā)現(xiàn)只有Box1重新刷新了一遍,而Box2未重新加載組件,也就是PureComponent內(nèi)部做了淺比較相同的不會(huì)進(jìn)行更新。
為什么被稱為淺比較
淺比較是指對(duì)值類型進(jìn)行比較,而稍微復(fù)雜一點(diǎn)的引用類型(Object),就無法進(jìn)行判斷了,react內(nèi)部的更新都是淺比較。
export default () => { const [count, setCount] = React.useState({ num: 1 }); console.log('parent update'); const click = () => { const newCount = count; newCount.num = count.num + 1; setCount(newCount); console.log('update:', count) }; return ( <div> <Box1 /> <Box2 /> <button onClick={click}>+1</button> </div> ); };
此時(shí),父組件內(nèi)部的count為對(duì)象類型,此時(shí)進(jìn)行更新時(shí),頁面不會(huì)觸發(fā)任何更新,父組件也不會(huì)進(jìn)行刷新(由于是引用類型,newCount發(fā)生數(shù)據(jù)變化時(shí),count其實(shí)已經(jīng)發(fā)生變化,但是頁面并不會(huì)有任何的反應(yīng))。
由圖可見,子組件和父組件并沒有進(jìn)行刷新,均未打印。
小知識(shí)點(diǎn)
const的不可變定義也是只對(duì)于值類型而言,對(duì)于引用類型,還是依然可變。上述代碼云清并不會(huì)報(bào)錯(cuò)。
說明
上述的一切代碼都是建立在父組件自身更新的基礎(chǔ)上子組件才會(huì)刷新,如果我將setCount(count + 1)
改為setCount(count + 0)
,那么,父組件本身不會(huì)進(jìn)行刷新,子組件也就理所當(dāng)然的不會(huì)有任何變化。
另類的不更新
這里的父組件刷新帶動(dòng)子組件刷新有一種例外的情況。代碼如下
const Parent = ({ children }) => { const [count, setCount] = React.useState(1); console.log('parent update'); return ( <div> {children} <button onClick={() => setCount(count + 1)}>box2</button> </div> ); }; export default () => { return ( <Parent> <Box1 /> <Box2 /> </Parent> ); };
將父組件抽離出來,子組件以children的形式引入。 此時(shí)頁面點(diǎn)擊發(fā)生的變化為
會(huì)發(fā)現(xiàn)不管怎么點(diǎn)擊,只有Parent組件進(jìn)行刷新,子組件全部都毫無反應(yīng)。
這個(gè)原因我不得而知,可能是因?yàn)閞eact生成dom的時(shí)候問題,這個(gè)等待深入學(xué)習(xí)后再來解答。
總結(jié)
PureComponent多用于抽取本地緩存制作的下拉框組件或者是根據(jù)數(shù)據(jù)字典生成的展示組件,這種固定的組件基本在用戶使用時(shí)不會(huì)有任何的變化,只在登錄和頁面加載最開始生成。
以上就是Component與PureComponent解析的詳細(xì)內(nèi)容,更多關(guān)于Component PureComponent解析的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React Hooks常用場(chǎng)景的使用(小結(jié))
這篇文章主要介紹了React Hooks常用場(chǎng)景的使用,根據(jù)使用場(chǎng)景分別進(jìn)行舉例說明,幫助你認(rèn)識(shí)理解并可以熟練運(yùn)用 React Hooks 大部分特性,感興趣的可以了解一下2021-04-04React18從0實(shí)現(xiàn)dispatch?update流程
這篇文章主要為大家介紹了React18從0實(shí)現(xiàn)dispatch?update流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01原生實(shí)現(xiàn)一個(gè)react-redux的代碼示例
這篇文章主要介紹了原生實(shí)現(xiàn)一個(gè)react-redux的代碼示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06基于Webpack5 Module Federation的業(yè)務(wù)解耦實(shí)踐示例
這篇文章主要為大家介紹了基于Webpack5 Module Federation的業(yè)務(wù)解耦實(shí)踐示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12React+Node實(shí)現(xiàn)大文件分片上傳、斷點(diǎn)續(xù)傳秒傳思路
本文主要介紹了React+Node實(shí)現(xiàn)大文件分片上傳、斷點(diǎn)續(xù)傳秒傳思路,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02一文詳解如何使用React監(jiān)聽網(wǎng)絡(luò)狀態(tài)
在現(xiàn)代Web應(yīng)用程序中,網(wǎng)絡(luò)連接是至關(guān)重要的,通過監(jiān)聽網(wǎng)絡(luò)狀態(tài),我們可以為用戶提供更好的體驗(yàn),例如在斷網(wǎng)時(shí)顯示有關(guān)網(wǎng)絡(luò)狀態(tài)的信息,本文將介紹如何使用React監(jiān)聽網(wǎng)絡(luò)狀態(tài)的變化,并提供相應(yīng)的代碼示例2023-06-06