国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開(kāi)發(fā) > JS > 正文

React之PureComponent的使用作用

2024-05-06 16:45:09
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

React避免重復(fù)渲染

React在渲染出的UI內(nèi)部建立和維護(hù)了一個(gè)內(nèi)層的實(shí)現(xiàn)方式,它包括了從組件返回的React元素。這種實(shí)現(xiàn)方式使得React避免了一些不必要的創(chuàng)建和關(guān)聯(lián)DOM節(jié)點(diǎn),因?yàn)檫@樣做可能比直接操作JavaScript對(duì)象更慢一些,它被稱(chēng)之為“虛擬DOM”。

當(dāng)一個(gè)組件的props或者state改變時(shí),React通過(guò)比較新返回的元素和之前渲染的元素來(lái)決定是否有必要更新實(shí)際的DOM。當(dāng)他們不相等時(shí),React會(huì)更新DOM。

在一些情況下,你的組件可以通過(guò)重寫(xiě)這個(gè)生命周期函數(shù)shouldComponentUpdate來(lái)提升速度, 它是在重新渲染過(guò)程開(kāi)始前觸發(fā)的。 這個(gè)函數(shù)默認(rèn)返回true,可使React執(zhí)行更新:

shouldComponentUpdate(nextProps, nextState) { return true;}

舉例

如果想讓組件只在props.color或者state.count的值變化時(shí)重新渲染,你可以像下面這樣設(shè)定shouldComponentUpdate

class CounterButton extends React.Component { constructor(props) {  super(props);  this.state = {count: 1}; } shouldComponentUpdate(nextProps, nextState) {  if (this.props.color !== nextProps.color) {   return true;  }  if (this.state.count !== nextState.count) {   return true;  }  return false; } render() {  return (   <button    color={this.props.color}    onClick={() => this.setState(state => ({count: state.count + 1}))}>    Count: {this.state.count}   </button>  ); }}

在以上代碼中,shouldComponentUpdate只檢查props.colorstate.count的變化。如果這些值沒(méi)有變化,組件就不會(huì)更新。當(dāng)你的組件變得更加復(fù)雜時(shí),你可以使用類(lèi)似的模式來(lái)做一個(gè)“淺比較”,用來(lái)比較屬性和值以判定是否需要更新組件。這種模式十分常見(jiàn),因此React提供了一個(gè)輔助對(duì)象來(lái)實(shí)現(xiàn)這個(gè)邏輯 - 繼承自React.PureComponent。以下代碼可以更簡(jiǎn)單的實(shí)現(xiàn)相同的操作:

class CounterButton extends React.PureComponent { constructor(props) {  super(props);  this.state = {count: 1}; } render() {  return (   <button    color={this.props.color}    onClick={() => this.setState(state => ({count: state.count + 1}))}>    Count: {this.state.count}   </button>  ); }}

PureComponent

原理

當(dāng)組件更新時(shí),如果組件的 props 和 state 都沒(méi)發(fā)生改變, render 方法就不會(huì)觸發(fā),省去 Virtual DOM 的生成和比對(duì)過(guò)程,達(dá)到提升性能的目的。具體就是 React 自動(dòng)幫我們做了一層淺比較:

if (this._compositeType === CompositeTypes.PureClass) {  shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState);}

而 shallowEqual 又做了什么呢?會(huì)比較 Object.keys(state | props) 的長(zhǎng)度是否一致,每一個(gè) key 是否兩者都有,并且是否是一個(gè)引用,也就是只比較了第一層的值,確實(shí)很淺,所以深層的嵌套數(shù)據(jù)是對(duì)比不出來(lái)的。

問(wèn)題

大部分情況下,你可以使用React.PureComponent而不必寫(xiě)你自己的shouldComponentUpdate,它只做一個(gè)淺比較。但是由于淺比較會(huì)忽略屬性或狀態(tài)突變的情況,此時(shí)你不能使用它。

class ListOfWords extends React.PureComponent { render() {  return <div>{this.props.words.join(',')}</div>; }}class WordAdder extends React.Component { constructor(props) {  super(props);  this.state = {   words: ['marklar']  };  this.handleClick = this.handleClick.bind(this); } handleClick() {  // This section is bad style and causes a bug  const words = this.state.words;  words.push('marklar');  this.setState({words: words}); } render() {  return (   <div>    <button onClick={this.handleClick} />    <ListOfWords words={this.state.words} />   </div>  ); }}

在ListOfWords中,this.props.words是WordAdder中傳入的其state的一個(gè)引用。雖然在WordAdder的handelClick方法中被改變了,但是對(duì)于ListOfWords來(lái)說(shuō),其引用是不變的,從而導(dǎo)致并沒(méi)有被更新。

解決方法

在上面的問(wèn)題中可以發(fā)現(xiàn),當(dāng)一個(gè)數(shù)據(jù)是不變數(shù)據(jù)時(shí),可以使用一個(gè)引用。但是對(duì)于一個(gè)易變數(shù)據(jù)來(lái)說(shuō),不能使用引用的方式給到PureComponent。簡(jiǎn)單來(lái)說(shuō),就是我們?cè)赑ureComponent外層來(lái)修改其使用的數(shù)據(jù)時(shí),應(yīng)該給其賦值一個(gè)新的對(duì)象或者引用,從而才能確保其能夠進(jìn)行重新渲染。例如上面例子中的handleClick可以通過(guò)以下幾種來(lái)進(jìn)行修改從而確認(rèn)正確的渲染:

handleClick() { this.setState(prevState => ({  words: prevState.words.concat(['marklar']) }));}

或者

handleClick() { this.setState(prevState => ({  words: [...prevState.words, 'marklar'], }));};

或者針對(duì)對(duì)象結(jié)構(gòu):

function updateColorMap(oldObj) { return Object.assign({}, oldObj, {key: new value});}

immutable.js

Immutable.js是解決這個(gè)問(wèn)題的另一種方法。它通過(guò)結(jié)構(gòu)共享提供不可突變的,持久的集合:

  • 不可突變:一旦創(chuàng)建,集合就不能在另一個(gè)時(shí)間點(diǎn)改變。
  • 持久性:可以使用原始集合和一個(gè)突變來(lái)創(chuàng)建新的集合。原始集合在新集合創(chuàng)建后仍然可用。
  • 結(jié)構(gòu)共享:新集合盡可能多的使用原始集合的結(jié)構(gòu)來(lái)創(chuàng)建,以便將復(fù)制操作降至最少?gòu)亩嵘阅堋?/li>
// 常見(jiàn)的js處理const x = { foo: 'bar' };const y = x;y.foo = 'baz';x === y; // true// 使用 immutable.jsconst SomeRecord = Immutable.Record({ foo: null });const x = new SomeRecord({ foo: 'bar' });const y = x.set('foo', 'baz');x === y; // false

總結(jié)

PureComponent 真正起作用的,只是在一些純展示組件上,復(fù)雜組件使用的話(huà)shallowEqual 那一關(guān)基本就過(guò)不了。另外在使用的過(guò)程中為了確保能夠正確的渲染,記得 props 和 state 不能使用同一個(gè)引用哦。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JavaScript/Ajax教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 上饶县| 青海省| 革吉县| 东台市| 深泽县| 宾阳县| 麻江县| 西丰县| 大宁县| 简阳市| 建阳市| 和田市| 桦川县| 龙州县| 澎湖县| 资中县| 华宁县| 吉木萨尔县| 鸡东县| 古交市| 寿宁县| 永丰县| 璧山县| 南乐县| 盖州市| 玉田县| 崇州市| 乌兰浩特市| 香格里拉县| 西昌市| 司法| 涿鹿县| 淳安县| 陕西省| 灌南县| 镇坪县| 平远县| 龙游县| 赫章县| 镇江市| 田林县|