淺談React工作原理

Reactjs 起源于Facebook內(nèi)部項(xiàng)目,是一個(gè)用來(lái)構(gòu)建用戶界面的 javascript 庫(kù),相當(dāng)于MVC架構(gòu)中的V層框架,與市面上其他框架不同的是,React 把每一個(gè)組件當(dāng)成了一個(gè)狀態(tài)機(jī),組件內(nèi)部通過(guò)state來(lái)維護(hù)組件狀態(tài)的變化,當(dāng)組件的狀態(tài)發(fā)生變化時(shí),React通過(guò)虛擬DOM技術(shù)來(lái)增量并且高效的更新真實(shí)DOM。本文將對(duì)React 的這些特點(diǎn)進(jìn)行簡(jiǎn)單的介紹。

公司主營(yíng)業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)推出鹽田免費(fèi)做網(wǎng)站回饋大家。

一個(gè)簡(jiǎn)單的React組件 —— HelloReact 

考慮到有的同學(xué)還不曾了解過(guò)React,我們先來(lái)寫(xiě)一個(gè)簡(jiǎn)單的React組件,讓大家一睹為快!

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// 創(chuàng)建一個(gè)HelloReact組件

var HelloReact = React.createClass({

    render:function(){

        return (

            <div>

                 Hello React!

            </div>

        )

    }

});

// 使用HelloReact組件

ReactDOM.render(

    <HelloReact />,

    document.querySelector('body')

)

這樣就定義了一個(gè)React組件,當(dāng)然要運(yùn)行這段代碼是有條件的,需要引入React庫(kù),還需要引入JSX語(yǔ)法轉(zhuǎn)換庫(kù),這里不多說(shuō)了,這些基礎(chǔ)的東西還需要各位親自實(shí)踐才好!

React 核心技術(shù) —— 虛擬DOM(Virtual DOM)

在前端開(kāi)發(fā)的過(guò)程中,我們經(jīng)常會(huì)做的一件事就是將變化的數(shù)據(jù)實(shí)時(shí)更新到UI上,這時(shí)就需要對(duì)DOM進(jìn)行更新和重新渲染,而頻繁的DOM操作通常是性能瓶頸產(chǎn)生的原因之一,有時(shí)候我們會(huì)遇到這樣一種尷尬的情況:比如有一個(gè)列表數(shù)據(jù),當(dāng)用戶執(zhí)行刷新操作時(shí),Ajax會(huì)重新從后臺(tái)請(qǐng)求數(shù)據(jù),即使新請(qǐng)求的數(shù)據(jù)和上次完全相同,DOM也會(huì)被全部更新一遍并進(jìn)行重新渲染,這樣就產(chǎn)生了不必要的性能開(kāi)銷。

React為此引入了虛擬DOM(Virtual DOM)機(jī)制:對(duì)于每一個(gè)組件,React會(huì)在內(nèi)存中構(gòu)建一個(gè)相對(duì)應(yīng)的DOM樹(shù),基于React開(kāi)發(fā)時(shí)所有的DOM構(gòu)造都是通過(guò)虛擬DOM進(jìn)行,每當(dāng)組件的狀態(tài)發(fā)生變化時(shí),React都會(huì)重新構(gòu)建整個(gè)DOM數(shù)據(jù),然后將當(dāng)前的整個(gè)DOM樹(shù)和上一次的DOM樹(shù)進(jìn)行對(duì)比,得出DOM結(jié)構(gòu)變化的部分(Patchs),然后將這些Patchs 再更新到真實(shí)DOM中。整個(gè)過(guò)程都是在內(nèi)存中進(jìn)行,因此是非常高效的。借用一張圖可以清晰的表示虛擬DOM的工作機(jī)制:

React 生命周期

React 把每個(gè)組件都當(dāng)作一個(gè)狀態(tài)機(jī)來(lái)維護(hù)和管理,因此每個(gè)組件都擁有一套完整的生命周期,大致可以分為三個(gè)過(guò)程:初始化、更新和銷毀。生命周期的每一個(gè)過(guò)程都明確的反映了組件的狀態(tài)變化。對(duì)于開(kāi)發(fā)來(lái)說(shuō)就能很容易的把握組件的每個(gè)狀態(tài),不同的狀態(tài)時(shí)期做對(duì)應(yīng)的事情,互不干擾。以下是和組件生命周期相關(guān)的幾個(gè)方法:

1

2

3

4

5

6

7

8

9

getDefaultProps //創(chuàng)建組建

getInitialState  //實(shí)例化狀態(tài)

componentWillMount  //掛載前

componentDidMount //掛載后

componentWillReceiveProps //屬性被改變時(shí)

shouldComponentUpdate //是否更新

componentWillUpdate //更新前

componentDidUpdate //更新后

componentWillUnmount //銷毀前

初始化

對(duì)于外部系統(tǒng)來(lái)說(shuō),組件是一個(gè)獨(dú)立存在的封閉系統(tǒng),內(nèi)部的邏輯被隱藏,只對(duì)外暴露傳遞數(shù)據(jù)的接口,而React為我們提供了兩種方式來(lái)向組件傳遞數(shù)據(jù),即 props 和 state。

props 是在調(diào)用 ReactDOM.render() 時(shí)通過(guò)標(biāo)簽屬性xxx傳遞,然后通過(guò) this.props.xxx 來(lái)獲取,getDefaultProps 允許你為組件設(shè)置一個(gè)默認(rèn)的props值,在沒(méi)有傳遞props的情況下顯示默認(rèn)值。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

// 創(chuàng)建HelloReact組件

var HelloReact = React.createClass({

    /**

     * 當(dāng)設(shè)置props的默認(rèn)值 當(dāng)沒(méi)有傳遞時(shí)顯示默認(rèn)值

     * @return {}

     */

    getDefaultProps:function(){

       return {

           data:"暫無(wú)數(shù)據(jù)"

       }

    },

    render:function(){

        return (

            <div>

               //顯示data,當(dāng)props發(fā)生變化時(shí)會(huì)自動(dòng)更新

               {this.props.data}

            </div>

        )

    }

});//傳遞props屬性data

ReactDOM.render(

   <HelloReact data={"Hello React!"} />,

   document.querySelector('body')

)

和 props 不同的是,state不能通過(guò)外部傳遞,因此在使用state之前,需要在 getInitialState 中為state設(shè)置一個(gè)默認(rèn)值,然后才能通過(guò) this.state.xxx 來(lái)訪問(wèn),當(dāng)組件被掛載完成時(shí),觸發(fā) componentDidMount 方法,我們可以在這里通過(guò)Ajax請(qǐng)求服務(wù)器數(shù)據(jù),然后再通過(guò) setState() 把state的值設(shè)置為真實(shí)數(shù)據(jù)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

// 創(chuàng)建HelloReact組件

var HelloReact = React.createClass({

    /**

     * 設(shè)置組件的初始值

     * @returns {{data: Array, msg: string}}

     */

    getInitialState:function(){

        return {

            data:"數(shù)據(jù)加載中..." //初始值為[]

        }

    },

    /**

     * 掛載后首次加載數(shù)據(jù)

     */

    componentDidMount:function(){

        this.requestData();//請(qǐng)求數(shù)據(jù)

    },

    /**

     * 請(qǐng)求后臺(tái)數(shù)據(jù)

     */

    requestData:function(){

        $.ajax({

            url:'xxxx.ashx',

            data:{},

            success:function(data){

                this.setState({

                    data:data  //通過(guò)setState()更新服務(wù)器數(shù)據(jù)

                })

            }

        }.bind(this))

    },

    render:function(){

        return (

            <div>

               {this.state.data}

            </div>

        )

    }

});

ReactDOM.render(

    <HelloReact  />,

    document.querySelector('body')

)

更新

props屬性是只讀的,如果想要改變props的值,只能通過(guò)重新調(diào)用render()來(lái)傳遞新的props,但要注意的是,重新執(zhí)行render()組件不會(huì)被重新掛載,而是通過(guò)虛擬DOM技術(shù)進(jìn)行增量更新和渲染,這時(shí)還會(huì)觸發(fā) componentWillReceiveProps 方法,并將新的props作為參數(shù)傳遞,你可以在這里對(duì)新的props進(jìn)行處理。

相比props,state天生就是用來(lái)反映組件狀態(tài)的,因此它的值是可以被改變的,當(dāng)state的值被改變時(shí),通過(guò)setState就可以改變state的值,React同樣也是采用虛擬DOM技術(shù)來(lái)計(jì)算需要被更新的部分,而不是牽一發(fā)動(dòng)全身的更新和渲染。

當(dāng) props 和 state 的狀態(tài)發(fā)生變化后,組件在即將更新之前還會(huì)觸發(fā)一個(gè)叫 shouldConponentUpdate 的方法,如果 shouldConponentUpdate 返回的是 true,不管props和state 的值和上一次相比有沒(méi)有變化,React 都會(huì)老老實(shí)實(shí)的進(jìn)行對(duì)比。此時(shí),如果你確定以及肯定兩次數(shù)據(jù)沒(méi)有變化,那就讓 shouldConponentUpdate 返回 false,React就不會(huì)進(jìn)行diff了,更不會(huì)重新渲染了。瞬間省去了diff的時(shí)間。

銷毀

當(dāng)組件從DOM中被移除時(shí),React會(huì)銷毀之。在銷毀之前,細(xì)心的React還觸發(fā) componentWillUnmount 來(lái)通知你,看你最后有沒(méi)有什么話想對(duì)這個(gè)即將銷毀的組件說(shuō),當(dāng)然你沒(méi)什么事就不用了。

什么時(shí)候用props,什么時(shí)候用state

我們已經(jīng)知道可以通過(guò)props和state兩種方式向組件傳遞數(shù)據(jù),props是只讀的不能被改變,而 state 是用來(lái)反映一個(gè)組件的狀態(tài),是可以改變的。因此,當(dāng)組件所需要的數(shù)據(jù)在調(diào)用時(shí)是已經(jīng)確定的,不頻繁發(fā)生變化的,就可以使用props來(lái)傳遞,相反,當(dāng)組件所需要的數(shù)據(jù)在調(diào)用時(shí)不能確定,需要等待異步回調(diào)時(shí)才能確定,比如ajax請(qǐng)求數(shù)據(jù),input的onchange事件,這時(shí)就需要使用state來(lái)記錄和改變這些值得變化。

當(dāng)前標(biāo)題:淺談React工作原理
文章位置:http://muchs.cn/article30/ipggpo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作定制開(kāi)發(fā)、網(wǎng)站設(shè)計(jì)公司、網(wǎng)站建設(shè)建站公司、企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作