ReactNative優(yōu)化之Public Class Fields

問題:
React中點(diǎn)擊事件onClick中需要訪問this,一般代碼是:

class App extends Component {
  state = {counter: 0}

  constructor() {
    super()

    // Like homework or situps; something you have to do :(
    this.incrementCounter = this.incrementCounter.bind(this) 
  }

  incrementCounter() {
    this.setState(ps => {
      return {counter: ps.counter + 1}
    })
  }

  render() {
    return (
      <div>
        <p>
          <button onClick={this.incrementCounter}>Increment</button>
        </p>
        <h1>{this.state.counter}</h1>
      </div>
    )
  }
}

一個(gè)方法incrementCounter寫了4個(gè)地方言疗,有人可能會做出以下優(yōu)化:
在渲染函數(shù)中添加一個(gè)匿名箭頭函數(shù),箭頭函數(shù)自動綁定this

class App extends Component {
  state = {counter: 0}

  render() {
    return (
      <div>
        <p>
          <button onClick={() => {
            this.setState(ps => {
              return {counter: ps.counter + 1}
            })
          }}>Increment</button>
        </p>
        <h1>{this.state.counter}</h1>
      </div>
    )
  }
}

結(jié)果是短了岁忘,但是這么做有個(gè)致命的問題舵稠,每次渲染都會創(chuàng)建一個(gè)新的函數(shù),我們一個(gè)新的組件<MyCustomButton /> 可能被迫每次都重新渲染嗓违,除非你重寫了自己的shouldComponentUpdate

在代碼量和工程量小的項(xiàng)目中九巡,這沒有什么,當(dāng)復(fù)雜的大型項(xiàng)目中蹂季,這是致命的冕广。

image.png

解決方案

使用Babel的 public class field

class App extends Component {
  state = {counter: 0}

  incrementCounter = () => {
    this.setState(ps => {
      return {counter: ps.counter + 1}
    })
  }

  render() {
    return (
      <div>
        <p>
          <button onClick={this.incrementCounter}>Increment</button>
        </p>
        <h1>{this.state.counter}</h1>
      </div>
    )
  }
}

1.綁定了this
2.書寫少了,不需要在構(gòu)造函數(shù)中bind了
3.因?yàn)樽詣咏壎ǔソ啵瘮?shù)不會再次創(chuàng)建撒汉,子組件非常容易成為PureComponent

測試

整體例子代碼

import React, { Component, PureComponent } from 'react';
import logo from './logo.svg';
import './App.css';

import Perf from 'react-addons-perf'
window.Perf = Perf

class MyButton extends Component {
    render() {
        console.log("component render...")
        return (
            <div>
                <button onClick={this.props.onClicked} >點(diǎn)擊我</button>
            </div>
        )
    }
}

class MyButton extends PureComponent {
    render() {
        console.log("PureComponent render...")
        return (
            <div>
                <button onClick={this.props.onClicked} >點(diǎn)擊我</button>
            </div>
        )
    }
}


const MyButton = ({
    onClicked
}) => {
    console.log("stateless function render...")
    return (
             <div>
                <button onClick={onClicked} >點(diǎn)擊我</button>
            </div>
    )
}



class App extends Component {

    state = {
        counter: 0
    }

    onClickedMe = () => {
        this.setState(ps => {
                return {
                    counter : ps.counter + 1
                }
            }
        )

    }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
          
          <MyButton onClicked={this.onClickedMe} >點(diǎn)擊我</MyButton>

          <h1>{this.state.counter}</h1>
      </div>
    )
  }
}

export default App;

1.componet組件

  • 每次點(diǎn)擊打印component render...
  • 按鈕組件渲染次數(shù)=點(diǎn)擊次數(shù)
  • 沒有任何渲染優(yōu)化


    image.png

2.PureComponent重載了shouldComponentUpdate,進(jìn)行shallowCompare優(yōu)化后

  • 每次點(diǎn)擊不打印 PureComponent render...
  • 按鈕組件渲染次數(shù)=0


    image.png

3.stateless function

  • 結(jié)果同component父能,只是可讀性更好神凑,但是渲染上并沒有發(fā)任何優(yōu)勢


    image.png
It should be noted that stateless functional components don't have the upper hand in terms of optimization and performance because they don't have a ShouldComponentUpdate() hook. This might change in future versions of React, where functional components might be optimized for better performance. However, if you're not critical of the performance, you should stick to functional components for the view/presentation and stateful class components for the container.

總結(jié)

如果沒有渲染上的影響,盡量使用stateless functional component何吝,畢竟可讀性好溉委。PureComponent可以優(yōu)化但是如果是可變的對象或者數(shù)組,注意淺比較易引起不刷新的bug.

參考:
public-class-fields
Stateful vs. Stateless Functional Components in React
Optimizing React Performance with Stateless Components

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末爱榕,一起剝皮案震驚了整個(gè)濱河市瓣喊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黔酥,老刑警劉巖藻三,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異跪者,居然都是意外死亡棵帽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門渣玲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逗概,“玉大人,你說我怎么就攤上這事忘衍∮馍唬” “怎么了卿城?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铅搓。 經(jīng)常有香客問我瑟押,道長,這世上最難降的妖魔是什么星掰? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任多望,我火速辦了婚禮,結(jié)果婚禮上氢烘,老公的妹妹穿的比我還像新娘便斥。我一直安慰自己,他們只是感情好威始,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著像街,像睡著了一般黎棠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上镰绎,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天脓斩,我揣著相機(jī)與錄音,去河邊找鬼畴栖。 笑死随静,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吗讶。 我是一名探鬼主播燎猛,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼照皆!你這毒婦竟也來了重绷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤膜毁,失蹤者是張志新(化名)和其女友劉穎昭卓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘟滨,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡候醒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了杂瘸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片倒淫。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖胧沫,靈堂內(nèi)的尸體忽然破棺而出昌简,到底是詐尸還是另有隱情占业,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布纯赎,位于F島的核電站谦疾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏犬金。R本人自食惡果不足惜念恍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望晚顷。 院中可真熱鬧峰伙,春花似錦、人聲如沸该默。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栓袖。三九已至匣摘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間裹刮,已是汗流浹背音榜。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捧弃,地道東北人赠叼。 一個(gè)月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像违霞,于是被迫代替她去往敵國和親嘴办。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理买鸽,服務(wù)發(fā)現(xiàn)户辞,斷路器,智...
    卡卡羅2017閱讀 134,702評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法癞谒,類相關(guān)的語法底燎,內(nèi)部類的語法,繼承相關(guān)的語法弹砚,異常的語法双仍,線程的語...
    子非魚_t_閱讀 31,664評論 18 399
  • 深入JSX date:20170412筆記原文其實(shí)JSX是React.createElement(componen...
    gaoer1938閱讀 8,073評論 2 35
  • react 基本概念解析 react 的組件聲明周期 react 高階組件,context, redux 等高級...
    南航閱讀 1,070評論 0 1
  • 九 “K君桌吃,我開動了朱沃。”由美略...
    海底的阿芙羅蒂閱讀 316評論 0 0