欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React之PureComponent的使用作用

 更新時(shí)間:2018年07月10日 10:35:16   作者:冷星  
這篇文章主要介紹了React之PureComponent的使用作用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

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ì)象更慢一些,它被稱之為“虛擬DOM”。

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

在一些情況下,你的組件可以通過重寫這個(gè)生命周期函數(shù)shouldComponentUpdate來提升速度, 它是在重新渲染過程開始前觸發(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的變化。如果這些值沒有變化,組件就不會(huì)更新。當(dāng)你的組件變得更加復(fù)雜時(shí),你可以使用類似的模式來做一個(gè)“淺比較”,用來比較屬性和值以判定是否需要更新組件。這種模式十分常見,因此React提供了一個(gè)輔助對(duì)象來實(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 都沒發(fā)生改變, render 方法就不會(huì)觸發(fā),省去 Virtual DOM 的生成和比對(duì)過程,達(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ì)比不出來的。

問題

大部分情況下,你可以使用React.PureComponent而不必寫你自己的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來說,其引用是不變的,從而導(dǎo)致并沒有被更新。

解決方法

在上面的問題中可以發(fā)現(xiàn),當(dāng)一個(gè)數(shù)據(jù)是不變數(shù)據(jù)時(shí),可以使用一個(gè)引用。但是對(duì)于一個(gè)易變數(shù)據(jù)來說,不能使用引用的方式給到PureComponent。簡(jiǎn)單來說,就是我們?cè)赑ureComponent外層來修改其使用的數(shù)據(jù)時(shí),應(yīng)該給其賦值一個(gè)新的對(duì)象或者引用,從而才能確保其能夠進(jìn)行重新渲染。例如上面例子中的handleClick可以通過以下幾種來進(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è)問題的另一種方法。它通過結(jié)構(gòu)共享提供不可突變的,持久的集合:

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

// 使用 immutable.js

const SomeRecord = Immutable.Record({ foo: null });
const x = new SomeRecord({ foo: 'bar' });
const y = x.set('foo', 'baz');
x === y; // false

總結(jié)

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

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

相關(guān)文章

  • React中的useEffect四種用法分享

    React中的useEffect四種用法分享

    這篇文章主要給大家分享React中的useEffect四種用法,useEffect中 觸發(fā)更新,重復(fù)的 useEffect,依賴值觸發(fā)回調(diào),useEffect 的返回值,通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • React基于路由的代碼分割技術(shù)詳解

    React基于路由的代碼分割技術(shù)詳解

    這篇文章主要為大家介紹了React基于路由的代碼分割技術(shù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 使用React.forwardRef傳遞泛型參數(shù)

    使用React.forwardRef傳遞泛型參數(shù)

    這篇文章主要介紹了使用React.forwardRef傳遞泛型參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • React中useCallback useMemo到底該怎么用

    React中useCallback useMemo到底該怎么用

    在React函數(shù)組件中,當(dāng)組件中的props發(fā)生變化時(shí),默認(rèn)情況下整個(gè)組件都會(huì)重新渲染。換句話說,如果組件中的任何值更新,整個(gè)組件將重新渲染,包括沒有更改values/props的函數(shù)/組件。在react中,我們可以通過memo,useMemo以及useCallback來防止子組件的rerender
    2023-02-02
  • ReactNative 之FlatList使用及踩坑封裝總結(jié)

    ReactNative 之FlatList使用及踩坑封裝總結(jié)

    本篇文章主要介紹了ReactNative 之FlatList使用及踩坑封裝總結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • 基于React.js實(shí)現(xiàn)簡(jiǎn)單的文字跑馬燈效果

    基于React.js實(shí)現(xiàn)簡(jiǎn)單的文字跑馬燈效果

    剛好手上有一個(gè)要實(shí)現(xiàn)文字跑馬燈的react項(xiàng)目,然后ant-design上面沒有這個(gè)組件,于是只能自己手?jǐn)]一個(gè),文中的實(shí)現(xiàn)方法講解詳細(xì),希望對(duì)大家有所幫助
    2023-01-01
  • React特征Form?單向數(shù)據(jù)流示例詳解

    React特征Form?單向數(shù)據(jù)流示例詳解

    這篇文章主要為大家介紹了React特征Form?單向數(shù)據(jù)流示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 使用webpack5從0到1搭建一個(gè)react項(xiàng)目的實(shí)現(xiàn)步驟

    使用webpack5從0到1搭建一個(gè)react項(xiàng)目的實(shí)現(xiàn)步驟

    這篇文章主要介紹了使用webpack5從0到1搭建一個(gè)react項(xiàng)目的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 使用React手寫一個(gè)對(duì)話框或模態(tài)框的方法示例

    使用React手寫一個(gè)對(duì)話框或模態(tài)框的方法示例

    這篇文章主要介紹了使用React手寫一個(gè)對(duì)話框或模態(tài)框的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • JavaScript的React框架中的JSX語(yǔ)法學(xué)習(xí)入門教程

    JavaScript的React框架中的JSX語(yǔ)法學(xué)習(xí)入門教程

    這篇文章主要介紹了JavaScript的React框架中的JSX語(yǔ)法學(xué)習(xí)入門教程,React是由Facebook開發(fā)并開源的高人氣js框架,需要的朋友可以參考下
    2016-03-03

最新評(píng)論