深入理解React

讓我們一起學(xué)習(xí)React

React 是Facebook在2013 年開(kāi)源在github上的javaScript庫(kù),React把用戶(hù)界面抽象成一個(gè)個(gè)組件,如按鈕組件Button、對(duì)話框組件Dialog、日期組件 Calemdar 開(kāi)發(fā)者通過(guò)組合這些組件,最終得到功能豐富、可交互的頁(yè)面。通過(guò)引入jsx語(yǔ)法,復(fù)用組件變得非常容易,同時(shí)也能保證組件結(jié)構(gòu)清晰。有了組件這層抽象,React把代碼和真實(shí)渲染目標(biāo)隔離開(kāi)來(lái),除了可以再瀏覽器端渲染DOM來(lái)開(kāi)發(fā)網(wǎng)頁(yè)之外,還能用于開(kāi)發(fā)原生移動(dòng)應(yīng)用。

1.1 專(zhuān)注于視圖層

我們的應(yīng)用已經(jīng)變得前所未有的復(fù)雜,因而開(kāi)發(fā)工具也必須變得越來(lái)越強(qiáng)大,和Angular等框架不同,React并不是完整的,,MVC/MVVM 框架,它專(zhuān)注于提供清晰、簡(jiǎn)潔的View(視圖)層解決方案,而又與模板引擎不同,React不僅僅專(zhuān)注于view層的問(wèn)題,又是一個(gè)包括view和controller的庫(kù),對(duì)于復(fù)雜的應(yīng)用,可以根據(jù)業(yè)務(wù)場(chǎng)景自行選擇業(yè)務(wù)層框架,并根據(jù)需要搭配Flux、redux來(lái)使用。

React不像其他框架那樣提供; 許多復(fù)雜的概念與繁瑣的API 它以Minimal API interface為目標(biāo)只提供組件化相關(guān)的非常少量的API,同時(shí)為了保持靈活性,它沒(méi)有自創(chuàng)一套規(guī)則,而是盡可能的讓用戶(hù)使用原生的javaScript進(jìn)行開(kāi)發(fā),只要熟悉原生的javaScript并了解重要概念后,就可以很容易上手React應(yīng)用。

1.2 VirtualDOM

真實(shí)頁(yè)面對(duì)應(yīng)一個(gè)DOM樹(shù),在傳統(tǒng)頁(yè)面開(kāi)發(fā)模式中,每次需要更新頁(yè)面的時(shí)候,都要手動(dòng)操作DOM來(lái)進(jìn)行更新,如圖。

真實(shí)dom.png

DOM操作非常昂貴。我們都知道在前端開(kāi)發(fā)中,性能消耗最大的就是DOM更新操作,而且這部分代碼會(huì)讓整體項(xiàng)目代碼變得難以維護(hù)。React把真實(shí)的DOM數(shù)轉(zhuǎn)變成了javaScript對(duì)象樹(shù),也就是viretual DOM

虛擬dom.png

每一次數(shù)據(jù)更新后,重新計(jì)算 viretual DOM 并和上一次生成的 viretual DOM 做對(duì)比,對(duì)發(fā)生變化的部分做批量的更新,React 也提供了直觀的 shouldComponentUpdate 生命周期回調(diào)來(lái)減少數(shù)據(jù)變化后不必要的 viretual DOM對(duì)比過(guò)程,保證性能。

我們說(shuō) viretual DOM 提升了React的性能,但是這并不是React的唯一的亮點(diǎn),此外viretual DOM的渲染方法也比傳統(tǒng)的 DOM 操作好一些,但并不明顯,因?yàn)閷?duì)比DOM 節(jié)點(diǎn)也是需要計(jì)算資源的。

它最大的好處其實(shí)還在于方便和其他平臺(tái)進(jìn)行集成,比如React-native 是基于viretual DOM渲染出來(lái)的原生控件,因?yàn)镽eact組件可以映射為對(duì)應(yīng)的原生控件在輸出的時(shí)候,是輸出WEB DOM還是 Android控件 還是ios控件就由平臺(tái)決定了,因此,React-native 有一個(gè)口號(hào)——learn once,write anywhere

1.3 函數(shù)式編程

在過(guò)去,工業(yè)界的編程方式一直是以命令式編程為主,命令式編程解決的是做什么的問(wèn)題比如圖靈機(jī),而現(xiàn)代計(jì)算機(jī)就是一個(gè)經(jīng)歷了多次進(jìn)化的高級(jí)圖靈機(jī),如果說(shuō)人腦最擅長(zhǎng)的是分析問(wèn)題,那計(jì)算機(jī)擅長(zhǎng)的是執(zhí)行命令,電腦的運(yùn)算速度明顯快過(guò)人腦,命令式編程就像是在給電腦下命令,現(xiàn)在主要的編程語(yǔ)言(包括C和java)都是由命令式編程構(gòu)建起來(lái)的。

而函數(shù)式編程,對(duì)應(yīng)的是聲明式編程,它是人類(lèi)模仿自己的思考方式發(fā)明出來(lái)的,聲明式編程的本質(zhì)是lambda演算,試想當(dāng)我們操作數(shù)據(jù)的每一個(gè)元素并返回一個(gè)新的數(shù)組的時(shí)候,如果是計(jì)算機(jī)的思考方式則是需要一個(gè)新的數(shù)組然后遍歷原來(lái)的數(shù)組,并計(jì)算賦值;如果是人的思考方式,則是構(gòu)建一個(gè)規(guī)則,這個(gè)過(guò)程就變成構(gòu)建一個(gè)f函數(shù)作用在數(shù)組上,然后返回新的數(shù)組,這樣,計(jì)算可以被重復(fù)利用。

2.1 JSX語(yǔ)法

當(dāng)初學(xué)習(xí)React的時(shí)候,jsx是我們遇到的第一個(gè)新的概念,也許我們都是寫(xiě)習(xí)慣js程序的開(kāi)發(fā)者,對(duì)于類(lèi)似于靜態(tài)編譯并不感冒,早些年風(fēng)靡前端的coffeescript也因?yàn)镋S6標(biāo)準(zhǔn)化的加速推進(jìn),慢慢變成了茶語(yǔ)飯后的談資,面對(duì) React 我們又一次需要玩轉(zhuǎn)一門(mén)新的靜態(tài)轉(zhuǎn)譯語(yǔ)言,這一次,有什么不一樣呢?

2.2 JSX的由來(lái)

JSX和React有什么關(guān)系呢?簡(jiǎn)單來(lái)說(shuō),React為了方便View層組件化,承載了構(gòu)建HTML結(jié)構(gòu)化頁(yè)面的職責(zé),“從這點(diǎn)上來(lái)看,React 與其他 javaScript 模板語(yǔ)言有著許多異曲同工之處,但不同之處在于 React 是通過(guò)創(chuàng)建與更新虛擬元素(virtual element)來(lái)管理整個(gè) Virtual DOM 的。

其中,虛擬元素可以理解為和真實(shí)的元素的對(duì)應(yīng),它的構(gòu)建與更新都是在內(nèi)存中完成的,并不會(huì)影響真正渲染到DOM中去,在React中創(chuàng)建虛擬元素可以分為兩類(lèi),DOM元素(DOM element) 與組件元素(component element)分別對(duì)應(yīng)著原生DOM 元素和自定義元素,而JSX與創(chuàng)建元素的過(guò)程有著莫大的關(guān)聯(lián)。

接著,我們從這兩種元素的構(gòu)建開(kāi)始說(shuō)起

  • 1.DOM 元素
    從過(guò)往的經(jīng)驗(yàn)中知道,“Web 頁(yè)面是由一個(gè)個(gè) HTML 元素嵌套組合而成的。當(dāng)使用 javaScript 來(lái)描述這些元素的時(shí)候,這些元素可以簡(jiǎn)單地被表示成純粹的 JSON 對(duì)象。比如,現(xiàn)在需要描述一個(gè)按鈕(button),這用 HTML 語(yǔ)法表示非常簡(jiǎn)單:

      <button class="btn btn-blue">
        <em>Confirm</em>
      </button>
    

    其中包括了元素的類(lèi)型和屬性。如果轉(zhuǎn)成 JSON 對(duì)象,那么依然包括元素的類(lèi)型以及屬性:

    {
      type: 'button',
        props: {
        className: 'btn btn-blue',
        children: [{
          type: 'em',
          props: {
            children: 'Confirm'
          }
        }]
      }
    }
    

    這樣,我們就可以在js中創(chuàng)建Virtual DOM 元素了。

    在React中 到處都是可以復(fù)用的元素,這些元素并不是真實(shí)的實(shí)例,它只是讓React告訴開(kāi)發(fā)者,想要在屏幕上顯示什么。我們無(wú)法通過(guò)方法去調(diào)用這些元素,他們只是不可遍的描述對(duì)象

      1. 組件元素

    當(dāng)然,我們可以很方便地封裝上述的button 元素,得到一種構(gòu)建按鈕的公共方法:

    const Button = ({ color, text }) => {
      return {
        type: 'button',
        props: {
          className: `btn btn-${color}`,
          children: {
            type: 'em',
            props: {
              children: text,
            },
          },
        },
      };
    }

自然,當(dāng)我們要生成 DOM 元素中具體的按鈕時(shí),就可以方便地調(diào)用 Button({color: 'blue', text: 'Confirm'}) 來(lái)創(chuàng)建。

仔細(xì)思考這個(gè)過(guò)程可以發(fā)現(xiàn),Button 方法其實(shí)也可以作為元素而存在,方法名對(duì)應(yīng)了 DOM 元素類(lèi)型,參數(shù)對(duì)應(yīng)了 DOM 元素屬性,
那么它就具備了元素的兩大必要條件,這樣構(gòu)建的元素就是自定義類(lèi)型的元素,或者稱(chēng)之為組件元素。我們用JSON結(jié)構(gòu)來(lái)描述它:

  {
     type: Button,
     props: {
       color: 'blue',
       children: 'Confirm'
     }
   }

這也是 React 的核心思想之一。因?yàn)橛泄驳谋磉_(dá)方法,我們就可以讓元素們彼此嵌套或混合。這些層層封裝的組件元素,就是所謂的 React 組件,最終我們可以用遞歸渲染的方式構(gòu)建出完全的 DOM 元素樹(shù).

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,283評(píng)論 25 708
  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 14,084評(píng)論 2 59
  • React+Redux非常精煉,良好運(yùn)用將發(fā)揮出極強(qiáng)勁的生產(chǎn)力。但最大的挑戰(zhàn)來(lái)自于函數(shù)式編程(FP)范式。在工程化...
    小馬哥歸來(lái)閱讀 154,689評(píng)論 21 166
  • I. Words and express 1. They will trot out the hard-won w...
    夕夜Silence閱讀 224評(píng)論 0 1
  • 制造偽分布式 復(fù)制兩份redis.conf配置文件(為redis1.conf,redis2.conf) 修改red...
    想旅游的程序員閱讀 302評(píng)論 0 0

友情鏈接更多精彩內(nèi)容