React 僅僅只是你的界限

來源:互聯網
上載者:User

標籤:

React 起源於Facebook內部項目,是一個用來構建使用者介面的javascript庫,相當於MVC架構中的V層架構,與市面上其他架構不同的是,React 把每一個組件當成了一個狀態機器,組件內部通過state來維護組件狀態的變化,當組件的狀態發生變化時,React通過虛擬DOM技術來增量並且高效的更新真實DOM。本文將對React的這些特點進行簡單的介紹。

 

一個簡單的React組件 —— HelloReact 

考慮到有的同學還不曾瞭解過React,我們先來寫一個簡單的React組件,讓大家一睹為快!

// 建立一個HelloReact組件var HelloReact = React.createClass({    render:function(){        return (            <div>                 Hello React!            </div>        )    }});// 使用HelloReact組件ReactDOM.render(    <HelloReact />,    document.querySelector(‘body‘))

這樣就定義了一個React組件,當然要運行這段代碼是有條件的,需要引入React庫,還需要引入JSX文法轉換庫,這裡不多說了,這些基礎的東西還需要各位親自實踐才好!

 

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

在前端開發的過程中,我們經常會做的一件事就是將變化的資料即時更新到UI上,這時就需要對DOM進行更新和重新渲染,而頻繁的DOM操作通常是效能瓶頸產生的原因之一,有時候我們會遇到這樣一種尷尬的情況:比如有一個列表資料,當使用者執行重新整理操作時,Ajax會重新從後台請求資料,即使新請求的資料和上次完全相同,DOM也會被全部更新一遍並進行重新渲染,這樣就產生了不必要的效能開銷。

React為此引入了虛擬DOM(Virtual DOM)機制:對於每一個組件,React會在記憶體中構建一個相對應的DOM樹,基於React開發時所有的DOM構造都是通過虛擬DOM進行,每當組件的狀態發生變化時,React都會重新構建整個DOM資料,然後將當前的整個DOM樹和上一次的DOM樹進行對比,得出DOM結構變化的部分(Patchs),然後將這些Patchs 再更新到真實DOM中。整個過程都是在記憶體中進行,因此是非常高效的。借用一張圖可以清晰的表示虛擬DOM的工作機制:

 

React 的生命週期

React 把每個組件都當作一個狀態機器來維護和管理,因此每個組件都擁有一套完整的生命週期,大致可以分為三個過程:初始化、更新和銷毀。生命週期的每一個過程都明確的反映了組件的狀態變化。對於開發來說就能很容易的把握組件的每個狀態,不同的狀態時期做對應的事情,互不干擾。以下是和組件生命週期相關的幾個方法:

getDefaultProps —— 組件建立時

getInitialState —— 組件執行個體化狀態

componentWillMount —— 組件掛載前

componentDidMount —— 組件掛載後

componentWillReceiveProps —— 組件屬性被改變時

shouldComponentUpdate —— 組件是否更新

componentWillUpdate —— 組件更新前

componentDidUpdate —— 組件更新後

componentWillUnmount —— 組件銷毀前

 

初始化

對於外部系統來說,組件是一個獨立存在的封閉系統,內部的邏輯被隱藏,只對外暴露傳遞資料的介面,而React為我們提供了兩種方式來向組件傳遞資料,即 props 和 state。

props 是在調用ReactDOM.render() 時通過標籤屬性xxx傳遞,然後通過 this.props.xxx 來擷取,getDefaultProps允許你為組件設定一個預設的props值,在沒有傳遞props的情況下顯示預設值。

// 建立HelloReact組件var HelloReact = React.createClass({    /**     * 當設定props的預設值 當沒有傳遞時顯示預設值     * @return {}     */    getDefaultProps:function(){       return {           data:"暫無資料"       }    },    render:function(){        return (            <div>               //顯示data,當props發生變化時會自動更新               {this.props.data}            </div>        )    }});//傳遞props屬性dataReactDOM.render(   <HelloReact data={"Hello React!"} />,   document.querySelector(‘body‘))

和 props 不同的是,state不能通過外部傳遞,因此在使用state之前,需要在getInitialState中為state設定一個預設值,然後才能通過this.state.xxx來訪問,當組件被掛載完成時,觸發componentDidMount方法,我們可以在這裡通過Ajax請求伺服器資料,然後再通過setState()把state的值設定為真實資料。

// 建立HelloReact組件var HelloReact = React.createClass({    /**     * 設定組件的初始值     * @returns {{data: Array, msg: string}}     */    getInitialState:function(){        return {            data:"資料載入中..." //初始值為[]        }    },    /**     * 掛載後首次載入資料     */    componentDidMount:function(){        this.requestData();//請求資料    },    /**     * 請求後台資料     */    requestData:function(){        $.ajax({            url:‘xxxx.ashx‘,            data:{},            success:function(data){                this.setState({                    data:data  //通過setState()補救伺服器資料                })            }        }.bind(this))    },    render:function(){        return (            <div>               {this.state.data}            </div>        )    }});ReactDOM.render(    <HelloReact  />,    document.querySelector(‘body‘))

 

更新

props屬性是唯讀,如果想要改變props的值,只能通過重新調用render()來傳遞新的props,但要注意的是,重新執行render()組件不會被重新掛載,而是通過虛擬DOM技術進行累加式更新和渲染,這時還會觸發componentWillReceiveProps方法,並將新的props作為參數傳遞,你可以在這裡對新的props進行處理。

相比props,state天生就是用來反映組件狀態的,因此它的值是可以被改變的,當state的值被改變時,通過setState就可以改變state的值,React同樣也是採用虛擬DOM技術來計算需要被更新的部分,而不是牽一髮動全身的更新和渲染。

當props和state的狀態發生變化後,組件在即將更新之前還會觸發一個叫shouldConponentUpdate的方法,如果shouldConponentUpdate返回的是true,不管props和state的值和上一次相比有沒有變化,React都會老老實實的進行對比。此時,如果你確定以及肯定兩次資料沒有變化,那就讓shouldConponentUpdate返回false,React就不會進行diff了,更不會重新渲染了。瞬間省去了diff的時間,是不是很機智的說。

 

銷毀

當組件從DOM中被移除時,React會銷毀之。在銷毀之前,細心的React還觸發componentWillUnmount來通知你,看你最後有沒有什麼話想對這個即將逝去的組件說,當然你沒什麼事就不用了。

 

什麼時候用props,什麼時候用state

我們已經知道可以通過props和state兩種方式向組件傳遞資料,props是唯讀不能被改變,而state是用來反映一個組件的狀態,是可以改變的。因此,當組件所需要的資料在調用時是已經確定的,不頻繁發生變化的,就可以使用props來傳遞,相反,當組件所需要的資料在調用時不能確定,需要等待非同步回調時才能確定,比如ajax請求資料,input的onchange事件,這時就需要使用state來記錄和改變這些值得變化。

 

React 給前端帶來的反思

以上便是對React的一個簡單認識,React到底有多好?  我們需要反思,在WebApp橫行霸道的時代,各路優秀的JS庫百花齊放,旨在解決移動端的效能問題和開發效率。對於一個前端開發人員來說,既要跟上時代的步伐,也不能被這些新事物迷失了方向,每當一個新的事物被推出來之前,一定有一個強大的力量在背後做足了品牌封裝。因此,對於我們來說既不能盲目崇拜,也不能消極對待,取其精華,去其糟粕,在取與舍之間找到一個平衡,來開闊自己的眼界,因為React僅僅只是你的界限。

 

React 僅僅只是你的界限

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.