學習React有一段時間了, 一直想找個時間寫一個React的系列文章。忙裏抽閒,完成了第一篇。寫這系列文章的初衷是總結這段時間的技術學習,以及給那些想學習React的同窗們一點幫助。我會盡可能以通俗易懂的語言闡述我對React的理解,但願能照顧到更多的新手。相信你們應該都明白一個道理,最可以帶領你進步的,並非比你強不少不少的大牛,而是恰好比你走得快那麼一步的腳印。javascript
這是2018年現代前端框架的使用狀況統計,圖片來自JavaScript 如日中天,2018趨勢報告來啦!,數據僅供參考。能夠看到這是個前端框架三足鼎立的時代,選擇React並非由於其餘框架不夠好,而是React自己有其獨特的魅力,吸引着開發者的彙集。就比如喜歡一我的,並非由於其餘人很差才喜歡他,而是被他獨特的魅力所吸引才產生了感情。因此對新手來講,大可沒必要太過糾結於框架的選擇,框架只是個幫助咱們開發的工具而已。你只須要知道,React自己足夠強大,可以讓你在大前端的世界裏走的更遠!html
咱們從最簡單的Hello World開始,進入React的世界,使用的是最新的React 16版本。前端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="root"></div> // 引入react及react-dom庫 <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> // 引入babel <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script> // 在babel編譯的環境下執行 <script type="text/babel"> const vDom = <h1>Hello World</h1> const root = document.getElementById('root') ReactDOM.render(vDom, root) </script> </body> </html>
在使用React以前,咱們須要先引入React相關的js庫。java
除此以外,還需引入babel進行語法解析轉換。react
咱們來詳細解析下上面的demo,其實script標籤中一共就寫了3句代碼,但其中包含了React的核心知識點——虛擬DOM和JSX。git
<script type="text/babel"> const vDom = <h1>Hello World</h1> const root = document.getElementById('root') ReactDOM.render(vDom, root) </script>
JSX是React的靈魂,全稱JavaScript XML。顧名思義,它可讓你在JS中使用XML標記的方式去直接聲明界面的DOM,這是React獨有的語法糖。github
請看HelloWorld的例子算法
const vDom = <h1>Hello World</h1> // 建立h1標籤,右邊千萬不能加引號 const root = document.getElementById('root') // 找到<div id="root"></div>節點 ReactDOM.render(vDom, root) // 把建立的h1標籤渲染到root節點上
這裏咱們在JS裏直接建立了一個<h1>Hello World</h1>
標籤,並賦值給vDom,這就是JSX語法。
若是咱們將react庫的引入註釋掉
會發現瀏覽器中報錯
緣由就是原生JS語法並不支持直接聲明DOM標籤,這是JSX的語法,須要React.js庫的支持。瀏覽器
ReactDOM.render()
這個是react-dom庫中的方法,用於將你建立好的HTML模板(虛擬DOM節點)插入到某個節點上,並渲染到頁面上。第一個參數是HTML模板,第二個參數是指定的DOM節點。前端框架
在上述JSX語法中有幾個值得注意的地方:
<h1>Hello World</h1>
這是一個對象,叫作虛擬DOM對象,後面會講到。<script>
標籤的 type 屬性爲 text/babel
。因爲使用了JSX這種特殊的語法,咱們不能再像往常同樣,使用<script type="text/javascript">
來解析JSX,而要藉助babel來進行解析、轉換成JS。簡單來講,就是JSX賦予咱們在JS中直接建立HTML標籤的能力,由於HTML標籤實在是太弱小了。
固然咱們也能夠不使用JSX的語法建立DOM節點,直接使用React給咱們提供的普通JS寫法,React.createElement()
API來建立。
const vDom = React.createElement( 'h1', // 第一個參數是標籤名,例如h一、span、table... { className: 'hClass', id: 'hId' }, // 第二個參數是個對象,裏面存着標籤的一些屬性,例如id、class等,由於class是保留字,因此要寫成className的形式 'hello world' // 第三個參數是節點中的文本 ) const root = document.getElementById('root') ReactDOM.render(vDom, root)
能夠看到和以前的JSX寫法const vDom = <h1>Hello World</h1>
效果是同樣的
在使用React.createElement()
這種寫法時,咱們並不須要用babel進行解析,由於這自己就是JS的語法,JS引擎能夠解析。
其實本質上,JSX就是爲了簡化直接調用React.createElement()
API的一顆語法糖而已,他執行最終會被babel解析轉換爲React.createElement()
的形式,因此推薦使用JSX的語法來建立頁面的UI(也就是HTML的一些DOM)。
咱們之前在操做時,須要通過如下流程
建立節點 -> 找到插入位置 -> 插入節點,如果還有子節點,還須要繼續添加,一切都須要手動實現。
而使用React的JSX語法只須要const vDom = xxx
而後ReactDOM.render(vDom, root)
就能夠。
換句話說,之前都是過程式操做,你不只知道要作什麼,還須要本身手動去實現。而如今變成了聲明式操做,就比如在下命令同樣,你只須要下命令建立怎樣的DOM節點,而後下命令插入,中間的過程所有都由React框架幫你自動實現,讓開發者能夠徹底屏蔽DOM的操做。
{}
或括號()
,就用 JavaScript 規則解析咱們把Hello World的例子提高下
<script type="text/babel"> let title = 'Hello World' const vDom = ( <div> <h1>{title}</h1> </div> ) const root = document.getElementById('root') ReactDOM.render(vDom, root) </script>
上述代碼在執行時,當遇到<div>
的左箭頭括號時,使用HTML的解析規則,當遇到{title}
時,採用JS的規則解析,也就是獲取變量title的值。值得一提的是,若是須要建立嵌套的HTML結構,推薦使用()
括號括起來。
虛擬 DOM 是在 DOM 的基礎上創建的一個抽象層,咱們對DOM中的數據和狀態所作的任何改動,都會被自動且高效的同步到虛擬 DOM,最後再批量同步到 DOM 中。React會在內存中維護一個虛擬 DOM 樹,當咱們對這個樹進行讀或寫的時候,其實是對虛擬 DOM 進行的。當數據變化時,React會自動更新虛擬 DOM樹,而後拿新的虛擬DOM樹和舊的虛擬DOM樹進行對比(當中有DOM diff算法,這個以後再說),把不一樣的虛擬節點放到一個隊列裏,最終在渲染時一次批量更新這些隊列中的虛擬節點到真實DOM中,這是對DOM渲染效率上的一個質的提高。
React以JS爲中心,以JSX的獨特語法糖將"HTML"放到了JS裏,而JS遠比HTML要強大。所以,與其加強HTML讓其擁有邏輯,不如加強JS讓其支持標籤化,這樣一來既豐富了JS操控領域,又提高了頁面渲染的性能。因此,你如果新手也不要緊,只要你JS能力足夠強,相信必定能在React的世界裏策馬奔騰!
最後推薦幾個React的社區
React官方文檔:https://react.docschina.org/
React China:http://react-china.org/
React開源中國社區:https://www.oschina.net/trans...
個人github地址:https://github.com/FightingHao若是有什麼不懂的地方,歡迎評論,但願和你們一塊兒探討React有關的知識!