《React Native 精解與實戰》書籍連載「React 與 React Native 簡介」

来源:https://www.cnblogs.com/parry/archive/2018/08/09/rn_book_intro_react_and_reactnative.html
-Advertisement-
Play Games

此文是我的出版書籍《React Native 精解與實戰》連載分享,此書由機械工業出版社出版,書中詳解了 React Native 框架底層原理、React Native 組件佈局、組件與 API 的介紹與代碼實戰,以及 React Native 與 iOS、Android 平臺的混合開發底層原理講... ...


截圖

此文是我的出版書籍《React Native 精解與實戰》連載分享,此書由機械工業出版社出版,書中詳解了 React Native 框架底層原理、React Native 組件佈局、組件與 API 的介紹與代碼實戰,以及 React Native 與 iOS、Android 平臺的混合開發底層原理講解與代碼實戰演示,精選了大量實例代碼,方便讀者快速學習。

書籍還配套了視頻教程「80 節實戰課精通 React Native 開發」,此視頻課程建議配合書籍學習,書籍中原理性的東西講解的比較清晰,而視頻教程對於組件、API 等部分的代碼實戰開發講解比較直觀。

書籍相關所有資料請訪問:http://rn.parryqiu.com

這一章節中我們將對 React 與 React Native 的基本概念進行介紹。從 React 產生的背景到 React 的框架詳細介紹,同時也對 React 的底層實現原理進行了簡單的介紹,然後過渡到對 React Native 的基本概念進行了介紹。

這一章節你將對 React 與 React Native 框架的發展、框架之間的關係有一個基本的瞭解,具體的技術細節在後續的章節將有更加詳細的講解與實戰。

1.1 React 簡介

React 框架是一個非常優雅、現代的前端開發框架,下麵我們將對 React 框架產生的背景與 React 框架的發展歷史進行介紹,並通過一個小的實例更加直觀地瞭解 React 框架的結構以及核心特性,在此基礎上對 React 框架優秀性能表現的原因從底層進行了剖析。

1.1.1 React 產生的背景

React 框架最早孵化於 Facebook 內部,Jordan Walke 是框架的創始人。作為內部使用的框架,在 2011 年的時候 React 框架被用於 Facebook 的新聞流 (newsfeed)以及 2012 年使用在了 Instagram 項目上。在 2013 年五月美國的 JSConf 大會上,React 框架項目被宣佈了開源。

圖 1-1 為 GitHub 上 React 的開源項目截圖,GitHub 地址為:https://github.com/facebook/react/。

截圖
圖 1-1 GitHub 上的 React 項目

React 框架產生的緣由是在當時的技術背景下,前端 MVC (Model-View-Controller) 框架性能不能滿足 Facebook 項目的性能需求以及擴展需求,所以 Jordan Walke 索性就自己著手開始寫 React 框架,這真是一種值得學習的精神。

在 Facebook 內部極其複雜的項目中,當時面臨的一個問題是,MVC 架構的項目當 Model 和 View 有數據流動時,可能會出現雙向的數據流動,那麼項目的調試以及維護將變得異常複雜。

1.1.2 React 框架簡介

React 官方也說自己不是一個 MVC 框架 (https://reactjs.org/blog/2013/06/05/why-react.html),或者說 React 只專註於 MVC 框架設計模式中的 View 層面的實現。
為了大大減少傳統前端直接操作 DOM 的昂貴花費,React 使用 Virtual DOM (虛擬 DOM)進行 DOM 的更新。

圖 1-2 為 React 框架的基本結構,此圖清晰明瞭地描述出了 React 底層與前端瀏覽器的溝通機制。

截圖
圖 1-2 React 框架結構

React 的組件是用戶界面的最小元素,與外界的所有交互都通過 state 和 props 進行傳遞。通過這樣的組件封裝設計,使用聲明式的編程方式,使得 React 的邏輯足夠簡化,並可以通過模塊化開發逐步構建出項目的整體 UI。

React 框架中還有一個重要的概念是單向數據流,所有的數據流從父節點傳遞到子節點。假設父節點數據通過 props 傳遞到子節點,如果相對父節點(或者說相對頂層)傳遞的 props 值改變了,那麼其所有的子節點(預設在沒有使用 shouldComponentUpdate 進行優化的情況下)都會進行重新渲染,這樣的設計使得組件足夠扁平並且也便於維護。

以下的示例代碼演示了 React 框架基本組件定義以及單向數據流的傳遞。

完整代碼在本書配套源碼的 01-01-02 文件夾。

我們在 index.js 文件中定義 React 項目的入口,render 函數中使用了子組件 BodyIndex,並通過 props 傳遞了兩個參數,id 和 name,用於從父組件向子組件傳遞參數,這也是 React 框架中數據流的傳遞方式。

1.  /** 
2.   * 章節: 01-01-02 
3.   * index.js 定義了 React 項目的入口 
4.   * FilePath: /01-01-02/index.js 
5.   * @Parry 
6.   */  
7.    
8.  var React = require('react');  
9.  var ReactDOM = require('react-dom');  
10. import BodyIndex from './components/bodyindex';  
11. class Index extends React.Component {  
12.   
13.     //生命周期函數 componentWillMount,組件即將載入  
14.     componentWillMount(){  
15.         console.log("Index - componentWillMount");  
16.     }  
17.   
18.     //生命周期函數 componentDidMount,組件載入完畢  
19.     componentDidMount(){  
20.         console.log("Index - componentDidMount");  
21.     }  
22.   
23.     //頁面表現組件渲染  
24.     render() {  
25.         return (  
26.             <div>  
27.                 <BodyIndex id={1234567890} name={"IndexPage"}/>  
28.             </div>  
29.         );  
30.     }  
31. }  
32.   
33. ReactDOM.render(<Index/>, document.getElementById('example'));  

在子組件 BodyIndex 中,其自身定義了 state 值,並通過 setTimeout 函數在頁面載入 5 秒後進行 state 值的修改。頁面表現層代碼部分演示瞭如何讀取自身的 state 值以及讀取父組件傳遞過來的 props 值。

1.  /** 
2.   * 章節: 01-01-02 
3.   * bodyindex.js 定義了一個名為 BodyIndex 的子組件 
4.   * FilePath: /01-01-02/bodyindex.js 
5.   * @Parry 
6.   */  
7.    
8.  import React from 'react';  
9.  export default class BodyIndex extends React.Component {  
10.   constructor() {  
11.     super();  
12.     this.state = {  
13.       username: "Parry"  
14.     };  
15.   }  
16.   
17.   render() {  
18.     setTimeout(() => {  
19.       //5秒後更改一下 state  
20.       this.setState({username: "React"});  
21.     }, 5000);  
22.   
23.     return (  
24.       <div>  
25.         
26.         <h1>子組件頁面</h1>  
27.   
28.         <h2>當前組件自身的 state</h2>  
29.         <p>username: {this.state.username}</p>  
30.   
31.         <h2>父組件傳遞過來的參數</h2>  
32.         <p>id: {this.props.id}</p>  
33.         <p>name: {this.props.name}</p>  
34.   
35.       </div>  
36.     )  
37.   }  
38. }  

項目的 package.json 文件配置以及使用的相關框架版本如下,具體的配置方法以及意義後續章節會有詳細講解。

1.  {  
2.    "name": "01-01-02",  
3.    "version": "1.0.0",  
4.    "description": "",  
5.    "main": "index.js",  
6.    "scripts": {  
7.      "test": "echo \"Error: no test specified\" && exit 1"  
8.    },  
9.    "author": "",  
10.   "license": "ISC",  
11.   "dependencies": {  
12.     "babel-preset-es2015": "^6.14.0",  
13.     "babel-preset-react": "^6.11.1",  
14.     "babelify": "^7.3.0",  
15.     "react": "^15.3.2",  
16.     "react-dom": "^15.3.2",  
17.     "webpack": "^1.13.2",  
18.     "webpack-dev-server": "^1.16.1"  
19.   }  
20. } 

在命令行執行 webpack-dev-server 命令後,瀏覽器中的運行效果如圖 1-3 所示,並且在 5 秒後子組件的 state 定義的 username 值由 Parry 變成了 React。

你可以直接在本地編寫代碼運行測試或直接下載本書配套源碼直接運行,運行後,註意此 state 頁面值更新的部分,整個頁面沒有進行任何的重新刷新載入,而只是進行了局部的更新,背後的原理在下麵的一小節會展開講解。

截圖
圖 1-3 代碼在瀏覽器中的執行結果

1.1.3 React 底層原理

React 框架底層的核心為 Virtual DOM,也就是虛擬 DOM。此小節將介紹這個最主要的底層特性,只有在你理解了 React 框架底層的本質,才能更好地幫助你理解 React 框架的前端表現,併為後續章節討論 React Native 框架的性能優化進行一定的知識儲備。

傳統的 HTML 頁面更新頁面元素,或者說需要更新頁面,都是將整個頁面重新載入實現重繪,執行這樣的操作不管是對於伺服器還是在用戶體驗上,“花費”都是非常昂貴的。後來,開始有了 AJAX(Asynchronous JavaScript And XML)這樣的局部更新技術,實現了頁面局部組件的非同步更新,不過 AJAX 在代碼的編寫、維護、性能以及更新粒度的控制上還是沒有達到一個完美的狀態。

文檔對象模型(Document Object Model,簡稱 DOM),是 W3C 組織推薦的處理可擴展標誌語言的標準編程介面。在 HTML 網頁上,組織頁面(或文檔)的對象元素被組織在一個樹形結構中,用來表示文檔中對象的標準模型就稱為 DOM。

React 通過在框架底層設計了一個虛擬 DOM,此虛擬 DOM 與頁面上的真實 DOM 進行映射,當業務邏輯修改了 React 組件中的 state 部分,如上例中,子組件的 state 值,username 由 Parry 修改成了 React,React 框架底層的 diff 演算法會與頁面 DOM 比較計算,哪些部分更改了,通過比較虛擬 DOM 與真實 DOM 的差異,最終只更新真實 DOM 與虛擬 DOM 差異的部分。此計算過程是在記憶體中進行的,並最終只更新差異的部分,所以 React 在前端中的高性能表現正是來自於此底層的設計。

圖 1-4 展示了 React 中的虛擬 DOM 與頁面真實 DOM 之間的關係,之間的差異通過 React 框架底層的 diff 演算法進行計算。

截圖
圖 1-4 React 虛擬 DOM 與頁面真實 DOM

如果需要更加深入一步瞭解 React 在源碼級別的實現原理,可以參考我博客里從 React 的源碼角度對 React 底層批量更新 state 策略的分析文章。

o 深入理解 React JS 中的 setState
http://blog.parryqiu.com/2017/12/19/react_set_state_asynchronously/
o 從源碼的角度再看 React JS 中的 setState
http://blog.parryqiu.com/2017/12/29/react-state-in-sourcecode/
o 從源碼的角度看 React JS 中批量更新 State 的策略(上)
http://blog.parryqiu.com/2018/01/04/2018-01-04/
o 從源碼的角度看 React JS 中批量更新 State 的策略(下)
http://blog.parryqiu.com/2018/01/08/2018-01-08/

1.1.4 React 優勢

通過上面對 React 框架的簡介、代碼演示以及底層原理的解析得知,React 最大的優勢在於更新頁面 DOM 時,對比於之前的前端更新方案,效率大大提高。其實 React 並不會在 state 更改的第一時間就去執行 diff 並立即更新頁面 DOM,而是將多次操作匯聚成一次批量操作,這樣再次大大提升了頁面更新重繪的效率,這部分在分享的源碼分析文章中有詳細地講解,感興趣的朋友可以直接參考我博客中的對 React 框架的深入剖析。

使用 React 框架開發,我們不會通過 JavaScript 代碼直接操作前端真實 DOM,而是完全通過 state 以及 props 的變更引起頁面 DOM 的變更,這比 jQuery 等框架那樣進行大量的 DOM 查找與操作來得簡單、高效的多。

React 框架在開源生態下,已經有大量的相關開源框架與組件可供使用,非常適合項目的快速開發。
以上這些 React 框架的優勢,同時也會轉化成 React Native 框架的優勢,所以這些也是學習 React Native 框架的必備背景知識,希望大家深入體會與實戰。

1.2 React Native 簡介

在瞭解到了 React 框架的基本概念、發展歷史以及底層基本原理後,我們再來學習 React Native 的基本概念將變得更加容易。

下麵我們將介紹 React 與 React Native 的關係,在對 React Native 框架有了基本瞭解後,我們將會深深地體會到為什麼選擇 React Native 框架進行移動 App 開發是一個最佳的選擇。

1.2.1 React 與 React Native 關係

Facebook 曾致力於使用 HTML 5 進行移動端的開發,最終發現與原生的 App 相比,體驗上還是有非常大的差距,並且這種差距越來越大,特別是性能方面的差距。

最終,Facebook 放棄了 HTML 5 的技術方向,結合之前章節介紹的 React 框架的發展歷史,2015 年 3 月,Facebook 正式發佈了 React Native 框架,此框架專註於移動端 App 的開發。

在最初發佈的版本中,我們只可以使用 React Native 框架開發 iOS 平臺的 App,在 2015 年 9 月,Facebook 發佈了支持 Android 平臺的 React Native 框架。至此,React Native 框架真正實現了跨平臺的移動 App 開發,此消息簡直就是移動開發人員的福音。

圖 1-5 為 GitHub 上 React Native 的開源項目,GitHub 地址為:https://github.com/facebook/react-native/。

截圖
圖 1-5 GitHub 上 React Native 開源項目

1.2.2 React Native 簡介

React Native 框架在 React 框架的基礎上,底層通過對 iOS 平臺與 Android 平臺原生代碼的封裝與調用,結合前臺的 JavaScript 代碼,這樣我們就可以通過 JavaScript 代碼編寫出調用 iOS 平臺與 Android 平臺原生代碼的 App,調用原生代碼編寫的 App 的性能遠遠優於使用 HTML 5 開發的 App 性能,因為 HTML 5 開發的 App 只是在 HTML 5 外部包裹上一個程式外殼後在移動平臺上運行,在性能與可以實現的功能上都不能達到 React Native 框架的水準。

React Native 框架提供了原生組件與底層 API 供開發者使用,這些自帶的組件與 API 已足夠滿足移動端 App 的開發需求,後續章節會詳細展開講解這些組件與 API 的概念與使用實戰演示。

React Native 框架還提供了與 iOS 平臺、Android 平臺混合開發的介面,讓開發者可以在 React Native 中調用 iOS 平臺與 Android 平臺中任意的原生 API 與代碼,讓可以在原生平臺實現的任何功能都可以在 React Native 框架中得以實現,後續章節同樣會詳細展開講解併進行實戰開發。

在使用 React Native 框架開發移動平臺 App 的過程中,我們可以直接使用 CSS 進行頁面元素的佈局,這是 iOS 與 Android 原生移動平臺開發者簡直不可想象的事情。

開發人員在具備了 React 框架基礎知識後,可以更加快速地進行 React Native 框架的學習與開發。圖 1-6 為 React Native 官網截圖,代碼展示了我們只需要使用類似 HTML 5(JSX)的代碼就可以進行跨平臺的移動 App 開發。

截圖
圖 1-6 React Native 演示代碼

1.2.3 React Native 優勢

底層採用 React 框架,減少了我們的學習與開發成本,React Native 框架可以讓你真正跨越移動開發的鴻溝,不需要分開學習 iOS 平臺與 Android 平臺的特定語法、頁面佈局以及各平臺的特別處理技巧,使用一套 React Native 代碼的部署就可以覆蓋多個移動平臺。

React Native 性能優化的已足夠好,完全可以避開之前使用 HTML 5 開發移動 App 的性能障礙。
React Native 框架的 JavaScript Core 底層,可以讓 App 輕鬆實現更新操作,基本上更新一下 JavaScript 文件,整個 App 就完成了更新,非常適合用來開發 App 的熱更新。熱更新的功能在後續章節也會詳細講解與實戰開發。

React Native 框架同時也使得 App 的開發調試變得異常簡單,不需要像之前在多個平臺、多個語言、多個工具之間跳來跳去,React Native 開發的 App 在模擬器或真機中,只需要像刷新瀏覽器一樣就可以即時查看到代碼修改後的效果,並且還可以在 Chrome 瀏覽器中查看控制台輸出、加斷點、單步調試等等,整個過程完全就是 JavaScript 開發調試的體驗,整個開發的體驗非常暢快。

圖 1-7 為使用 React Native 框架開發時,在 iOS 系統下的開發調試選項截圖,非常的強大、方便。Android 平臺提供了同樣的調試選項。

截圖
圖 1-7 React Native 開發調試

1.3 React Native 前置知識點

在正式開始學習 React Native 框架前,我們梳理一下需要具備的一些基本知識,因為 React Native 畢竟是進行多平臺的移動 App 開發,涉及到的知識點比較多,而且底層的 React 框架有別於目前既有的一些前端框架知識,供你在學習前進行自我梳理與學習準備。

o 掌握 HTML 5 的基本知識;
o 掌握 JavaScript 的基礎知識,如果有 React 的基礎知識學習起來會更加地輕鬆;
o 掌握 CSS 佈局的基本知識,在 React Native 中會使用 CSS 直接進行頁面元素的佈局與樣式控制;
o 接觸過移動端的開發更好,項目的後期會涉及到兩個平臺的 App 打包、部署與上架,不過這些知識點後續章節都會進行講解;
o Node.js 以及 npm 包管理的知識,這部分後續章節同樣會有詳細地講解。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一,效果圖。 二,代碼。 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>html標題</title> </head> <body> <!--標題--> <h1>這是標題h1</h1> <h2>這是標題h2</h2> <h3>這 ...
  • 本節列舉了一些簡單的HTML例子,幫助大家更感性地認識HTML標簽。是不是對一些標簽還不熟悉?別擔心,後面幾個章節會有詳細說明,先跑幾個例子看看效果吧。 HTML文檔相關標簽所有HTML文檔必須以<!DOCTYPE html>聲明開頭。 HTML文檔則以<html>開頭,以</html>結尾。 HT ...
  • 什麼是HTML?HTML是一種標準的標記語言,用這種語言可以創建web頁面。 HTML是一種超文本標記語言HTML使用一些標記來描述頁面的結構HTML中的元素(elements)是構建頁面的基礎HTML用標簽(tags)代表網頁元素各種不同的標簽(如頭部標簽,表格標簽,圖片標簽)彼此分工又相互組合, ...
  • 棧(stack)又名堆棧,它是一種運算受限的線性表。其限制是 僅允許在表的一端進行插入和刪除運算 。這一端被稱為棧頂,相對地,把另一端稱為棧底。 一、實現一個棧類Stack 基於堆棧的特性,可以用數組做線性表進行存儲。 初始化 類的結構如下: 接下來,就是在原型上,對 、`出棧 清空棧 讀取棧頂 讀 ...
  • CSS介紹 學前端必備掌握 樣式, 為層疊樣式表,用來定義頁面的顯示效果,加強用戶的體驗樂趣,那麼如何用 到`html`中呢? style屬性方式 利用標簽中的 屬性來改變顯示樣式 在 中加入 標簽 鏈接方式 總結CSS 選擇器名稱 { 屬性名:屬性值; ……. } 屬性與屬性之間用 分號 隔開 屬 ...
  • 簡介 History對象最初設計用來表示視窗的瀏覽歷史,但是,出於隱私方面的原因,History對象不再允許腳本訪問已經訪問過的實際URL。雖然,我們不清楚歷史URL,但是,我們可以通過History對象的內置屬性方法進行跳轉。 對象屬性 length 該屬性代表著瀏覽器歷史列表中的URL數量。初始 ...
  • Javascript數組的5種迭代方法 數組當中定義了5個迭代方法,傳入這些方法中的函數會接受三個參數,數組項的值,該項在數組的位置,和數組對象本身,以下是5個迭代方法的作用。 1、every方法: 對數組中的每一項運行給定函數,如果該函數對每一項都返回true,則返回true。 2、filter方 ...
  • 網上有很多免費的線上電子書籍,沒有pdf格式,不方便離線閱讀,也不方便做記錄,所以找了幾個將線上內容製作成pdf文件的方法。 一、如果網站上的書籍內容沒有分頁,所有內容都直接顯示出來了,最簡單,直接將印表機設為PDF即可: 二、書籍內容分章節顯示,需要點擊鏈接重新請求數據切換的: 利用 telepo ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...