摘要:原文何時使用還是我開始轉(zhuǎn)向使用是因?yàn)樗且粋€更具性能的的版本。存在性能問題比較原始值值和對象引用是低耗時操作。這會有一個改變每個子組件的副作用,它將會造成他們?nèi)恐匦落秩?,即使?shù)據(jù)本身沒有發(fā)生變化。
原文:When to use Component or PureComponent?何時使用Component還是PureComponent?
我開始轉(zhuǎn)向使用PureCompoent是因?yàn)樗且粋€更具性能的Component的版本。雖然事實(shí)證明這是正確的,但是這種性能的提高還伴隨著一些附加的條件。讓我們深挖一下PureComponent,并理解為什么我們應(yīng)該使用它。
Component和PureComponent有一個不同點(diǎn)除了為你提供了一個具有淺比較的shouldComponentUpdate方法,PureComponent和Component基本上完全相同。當(dāng)props或者state改變時,PureComponent將對props和state進(jìn)行淺比較。另一方面,Component不會比較當(dāng)前和下個狀態(tài)的props和state。因此,每當(dāng)shouldComponentUpdate被調(diào)用時,組件默認(rèn)的會重新渲染。
淺比較101當(dāng)把之前和下一個的props和state作比較,淺比較將檢查原始值是否有相同的值(例如:1 == 1或者ture==true),數(shù)組和對象引用是否相同。
從不改變您可能已經(jīng)聽說過,不要在props和state中改變對象和數(shù)組,如果你在你的父組件中改變對象,你的“pure”子組件不將更新。雖然值已經(jīng)被改變,但是子組件比較的是之前props的引用是否相同,所以不會檢測到不同。
因此,你可以通過使用es6的assign方法或者數(shù)組的擴(kuò)展運(yùn)算符或者使用第三方庫,強(qiáng)制返回一個新的對象。
存在性能問題?比較原始值值和對象引用是低耗時操作。如果你有一列子對象并且其中一個子對象更新,對它們的props和state進(jìn)行檢查要比重新渲染每一個子節(jié)點(diǎn)要快的多。
其它解決辦法 不要在render的函數(shù)中綁定值假設(shè)你有一個項(xiàng)目列表,每個項(xiàng)目都傳遞一個唯一的參數(shù)到父方法。為了綁定參數(shù),你可能會這么做:
this.likeComment(user.id)} />
這個問題會導(dǎo)致每次父組件render方法被調(diào)用時,一個新的函數(shù)被創(chuàng)建,已將其傳入likeComment。這會有一個改變每個子組件props的副作用,它將會造成他們?nèi)恐匦落秩?,即使?shù)據(jù)本身沒有發(fā)生變化。
為了解決這個問題,只需要將父組件的原型方法的引用傳遞給子組件。子組件的likeComment屬性將總是有相同的引用,這樣就不會造成不必要的重新渲染。
然后再子組件中創(chuàng)建一個引用了傳入屬性的類方法:
class CommentItem extends PureComponent { ... handleLike() { this.props.likeComment(this.props.userID) } ... }不要在render方法里派生數(shù)據(jù)
考慮一下你的配置組件將從一系列文章中展示用戶最喜歡的十篇文章。
render() { const { posts } = this.props const topTen = posts.sort((a, b) => b.likes - a.likes).slice(0, 9) return //... }
每次組件重新渲染時topTen都將有一個新的引用,即使posts沒有改變并且派生數(shù)據(jù)也是相同的。這將造成列表不必要的重新渲染。
你可以通過緩存你的派生數(shù)據(jù)來解決這個問題。例如,設(shè)置派生數(shù)據(jù)在你的組件state中,僅當(dāng)posts更新時它才更新。
componentWillMount() { this.setTopTenPosts(this.props.posts) } componentWillReceiveProps(nextProps) { if (this.props.posts !== nextProps.posts) { this.setTopTenPosts(nextProps) } } setTopTenPosts(posts) { this.setState({ topTen: posts.sort((a, b) => b.likes - a.likes).slice(0, 9) }) }
如果你正在使用Redux,可以考慮使用reselect來創(chuàng)建"selectors"來組合和緩存派生數(shù)據(jù)。
結(jié)束語只要你遵循下列兩個簡單的規(guī)則就可以安全的使用PureComponent來代替Component:
- 雖然通常情況下易變性就是不好的,但是當(dāng)使用`PureComponent`時問題會變得復(fù)雜。 - 如果你在`render`方法中創(chuàng)建一個新的函數(shù),對象或者是數(shù)組那么你的做法(可能)是錯誤的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95194.html
摘要:首先是創(chuàng)建了一個構(gòu)造函數(shù),他的原型指到的原型然后創(chuàng)建了一個加上了和一樣的屬性這里為啥不用。的原型指向的實(shí)例修改原型的屬性使其正確指向的構(gòu)造函數(shù),并掛一個的屬性。 每次都信誓旦旦的給自己立下要好好學(xué)習(xí)react源碼的flag,結(jié)果都是因?yàn)槟硞€地方卡住了,或是其他原因沒看多少就放棄了。這次又給自己立個flag-堅(jiān)持看完react源碼。為了敦促自己,特開設(shè)這樣一個專欄來記錄自己的學(xué)習(xí)歷程,這...
摘要:函數(shù)組件上面我們探討了如何使用和的方法優(yōu)化類組件的性能。它的作用和類似,是用來控制函數(shù)組件的重新渲染的。其實(shí)就是函數(shù)組件的。 原文鏈接: Improving Performance in React Functional Component using React.memo 原文作者: Chidume Nnamdi 譯者: 進(jìn)擊的大蔥 推薦理由: 本文講述了開發(fā)React應(yīng)用時如...
摘要:本文針對技術(shù)棧,總結(jié)了一些最佳實(shí)踐,對編寫高質(zhì)量的代碼有一定的參考作用。二最佳實(shí)踐說明多用如果組件是純展示型的,不需要維護(hù)和生命周期,則優(yōu)先使用。理解并遵循這些最佳實(shí)踐,寫出來的代碼質(zhì)量會有一定的保證。 歡迎關(guān)注我的公眾號睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 在日常開發(fā)和 Code Revi...
摘要:只涉及了,其他均沒有自己實(shí)現(xiàn)。這種組件的復(fù)用性是最強(qiáng)的。所以會新建,只繼承的原型,不包括,以此來節(jié)省內(nèi)存。 showImg(https://segmentfault.com/img/remote/1460000019783989); 一、React.Component() GitHub:https://github.com/AttackXiaoJinJin/reactExplain/...
摘要:用這種方式創(chuàng)建組件時,并沒有對內(nèi)部的函數(shù),進(jìn)行綁定,所以如果你想讓函數(shù)在回調(diào)中保持正確的,就要手動對需要的函數(shù)進(jìn)行綁定,如上面的,在構(gòu)造函數(shù)中對進(jìn)行了綁定。 當(dāng)我們談起React的時候,多半會將注意力集中在組件之上,思考如何將頁面劃分成一個個組件,以及如何編寫可復(fù)用的組件。但對于接觸React不久,還沒有真正用它做一個完整項(xiàng)目的人來說,理解如何創(chuàng)建一個組件也并不那么簡單。在最開始的時候...
閱讀 2883·2021-09-22 15:20
閱讀 2958·2021-09-22 15:19
閱讀 3448·2021-09-22 15:15
閱讀 2382·2021-09-08 09:35
閱讀 2373·2019-08-30 15:44
閱讀 3004·2019-08-30 10:50
閱讀 3707·2019-08-29 16:25
閱讀 1586·2019-08-26 13:55