《React Native 精解與實戰》書籍連載「React Native 網路請求與列表綁定」

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

此文是我的出版書籍[《React Native 精解與實戰》](http://rn.parryqiu.com/)連載分享,此書由機械工業出版社出版,書中詳解了 React Native 框架底層原理、React Native 組件佈局、組件與 API 的介紹與代碼實戰,以及 React Native... ...


截圖

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

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

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

8.4 React Native 網路請求與列表綁定方案

下麵我們就通過結合 Fetch API 以及 React Native 框架中的列表組件,通過代碼實戰的形式進行這兩個重要知識點的學習。
首先我們數據獲取使用豆瓣的公開 API,獲取目前正在上映的 20 部電影的信息,豆瓣 API 地址為:https://api.douban.com/v2/movie/in_theaters?count=20,API 介面返回的 JSON 數據如圖 8-6 所示。

截圖
圖 8-6 豆瓣 API 返回的 JSON 數據

在此示例代碼中,將採用組件開發的思想,首頁載入 4 個 Tab,每一個 Tab 載入對應的頁面組件。這裡的列表載入在第一個 Tab 中,組件定義為 Home,在項目中建立的文件名為 home.js。
完整代碼在本書配套源碼的 08-03 文件夾。


1.  /** 
2.   * 章節: 08-03 
3.   * App.js 定義了項目的大結構,使用 4 個 Tab 進行佈局。 
4.   * FilePath: /08-03/ListDemo/App.js 
5.   * @Parry 
6.   */  
7.    
8.  import React, {Component} from 'react';  
9.  import {Platform, StyleSheet, Text, View, Image} from 'react-native';  
10. import TabNavigator from 'react-native-tab-navigator';  
11. import HomePage from './home';  
12.   
13. export default class App extends Component < {} > {  
14.   
15.   state = {  
16.     selectedTab: 'home'  
17.   };  
18.   
19.   _renderContent = (color : string, index : string) => {  
20.     switch (index) {  
21.       case "home":  
22.         return (<HomePage/>);  
23.     }  
24.   };  
25.   
26.   render() {  
27.     return (  
28.       <TabNavigator>  
29.         <TabNavigator.Item  
30.           selected={this.state.selectedTab === 'home'}  
31.           title="首頁"  
32.           renderIcon={() => <Image  
33.           style= { {
34.           width: 25,  
35.           height: 25  
36.          } } />
37.           source={require('./flux.png')}/>}  
38.           renderSelectedIcon={() => <Image  
39.           style= { {  
40.           width: 25,  
41.           height: 25  
42.          } } />
43.           source={require('./relay.png')}/>}  
44.           onPress={() => this.setState({selectedTab: 'home'})}>  
45.           {this._renderContent('#FFFFFF', 'home')}  
46.         </TabNavigator.Item>  
47.   
48.         ...... //此處省略了其他三個 Tab 的定義  
49.                //完整代碼在書籍的配套源碼中  
50.           
51.       </TabNavigator>  
52.     );  
53.   }  
54. }  

上面這段代碼為 App.js 的部分主要邏輯,註意在代碼的第 11 行導入外部 Home 組件的方法,以及針對之前 Tab 組件章節的邏輯修改了載入對應組件的方法,主要為代碼第 20 行的部分。


1.  /** 
2.   * 章節: 08-03 
3.   * home.js 定義了第一個 Tab 載入的頁面組件,用於載入豆瓣電影列表 
4.   *         同時演示了 ListView 綁定方法 
5.   * FilePath: /08-03/ListDemo/home.js 
6.   * @Parry 
7.   */  
8.    
9.  import React, {Component} from 'react';  
10. import {  
11.     Platform,  
12.     StyleSheet,  
13.     Text,  
14.     View,  
15.     Image,  
16.     ListView,  
17.     SafeAreaView  
18. } from 'react-native';  
19.   
20. export default class HomePage extends Component < {} > {  
21.   
22.     constructor(props) {  
23.         super(props);  
24.         this.state = {  
25.             dataSource: new ListView.DataSource({ //定義數據源  
26.                 rowHasChanged: (row1, row2) => row1 !== row2  
27.             }),  
28.             loaded: false  
29.         };  
30.     }  
31.   
32.     componentDidMount() {  
33.         this.fetchData(); //開始請求數據  
34.     };  
35.   
36.     fetchData() {  
37.         fetch("https://api.douban.com/v2/movie/in_theaters").then((response) => response.json()).then((responseData) => {  
38.             this.setState({  
39.                 dataSource: this  
40.                     .state  
41.                     .dataSource  
42.                     .cloneWithRows(responseData.subjects), //讀取返回的所有電影數據  
43.                 loaded: true  
44.             });  
45.         }).done();  
46.     };  
47.   
48.     render() {  
49.         return (  
50.             <View style={styles.container}>  
51.                 <ListView automaticallyAdjustContentInsets={false} //此選項可以修複掉會自動多出來的大約 10px 的空行  
52.                     dataSource={this.state.dataSource} renderRow={this._renderRow}/>  
53.             </View>  
54.         );  
55.     };  
56.   
57.     _renderRow(rowData, sectionID, rowID) {  
58.         return (  
59.             <SafeAreaView>  
60.                 <View style={styles.row}>  
61.                     <Image  
62.                         style={styles.thumb}  
63.                         source= { { 
64.                         uri: rowData.images.large  
65.                         } } />  
66.                     <View style={styles.texts}>  
67.                         <Text style={styles.textTitle}>  
68.                             {rowData.title}  
69.                         </Text>  
70.                         <Text style={styles.textTitle}>  
71.                             年份: {rowData.year}  
72.                         </Text>  
73.                         <Text style={styles.textTitle}>  
74.                             豆瓣評分: {rowData.rating.average}  
75.                         </Text>  
76.                     </View>  
77.                 </View>  
78.                 <View style={styles.separator}/>  
79.             </SafeAreaView>  
80.         );  
81.     };  
82. }  
83.   
84. var styles = StyleSheet.create({  
85.     container: {  
86.         flex: 1  
87.     },  
88.     row: {  
89.         flexDirection: 'row',  
90.         padding: 10  
91.     },  
92.     separator: {  
93.         height: 1,  
94.         backgroundColor: '#EEEEEE'  
95.     },  
96.     thumb: {  
97.         width: 60,  
98.         height: 80,  
99.         borderRadius: 2  
100.        },  
101.        textTitle: {  
102.            flex: 1,  
103.            textAlign: "left",  
104.            paddingLeft: 10,  
105.            fontWeight: "bold",  
106.            flexDirection: 'row',  
107.            color: "#666666"  
108.        },  
109.        texts:{  
110.            flexDirection: 'column',  
111.            paddingTop: 5  
112.        }  
113.    });  

上面代碼為 Home 組件的實現方法,下麵主要對代碼中的一些重要邏輯作一些說明:

  • 代碼在 17 行導入了一個新的 View 組件,SafeAreaView 用於在 iPhone X 下佈局 View 而控制整個 View 安全佈局於手機的可視區域中;

  • 代碼的第 25 - 27 行,定義了 ListView 的數據源,同時定義了 rowHasChanged 的邏輯;

  • 代碼第 32 行在生命周期 componentDidMount 中定義了從 API 中載入數據的方法;

  • 代碼第 36 - 46 行定義了從豆瓣 API 使用 Fetch API 請求數據的方法,註意對 Fetch API 返回的 Promise 對象的處理方法;

  • 代碼第 51 行定義了 ListView 綁定的方法,行渲染的方法為代碼中第 57 行定義的方法 _renderRow;

  • 代碼第 57 - 81 行定義了列表渲染的方法,使用 View 與 Text 組件進行了列表的展示佈局;

  • 後續的樣式定義如之前學習的樣式定義一樣,進行精細佈局控制即可。

項目運行在 iOS 平臺的效果如圖 8-7 所示,Android 平臺大家也可以直接下載本書配套源碼在本地學習、測試與運行。

截圖
圖 8-7 iOS 下的 ListView 運行效果

8.5 本章小結

列表綁定是 App 開發最常用的一個開發功能,你可以隨手打開自己手機上的 App 就會發現許多 App 的首頁都是進行了數據請求、列表綁定或列表數據刷新等動作,這也真是移動互聯網的魅力所在,用戶可以隨時獲取到最新的資訊信息。所以此章節是一個重要的章節,並從底層知識點到實戰代碼都進行了詳細地講解與演示,希望能幫助你開發出你的 App 的首頁列表組件。


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

-Advertisement-
Play Games
更多相關文章
  • canvas 繪製圖片是根據原始圖片的尺寸進行繪製,而不是根據利用屬性或樣式放大縮小後的圖片,所以要乘以原始圖片與現在圖片的比例。 ...
  • 在開發中總是忘記, 特意在此記錄 關鍵字: $event <div class="bed" v-on:click="updateBed(index,$event)">{{item.BedID}}<br>{{item.CriminalName}}</div> updateBed: function(i ...
  • 一:瞭解jquery裡面常用的事件 二:瞭解基礎動畫的實現 1:載入DOM 在JavaScript中使用window.onload事件作為窗體載入事件(它在頁面所有數據載入完成之後才會執行) 在jQuery裡面中使用 $(document).ready(function()) 作為窗體載入事件(在D ...
  • 1:載入DOM在JavaScript中使用window.onload事件作為窗體載入事件(它在頁面所有數據載入完成之後才會執行)在jQuery裡面中使用 $(document).ready(function()) 作為窗體載入事件(在DOM載入完成之後就會執行)2:事件綁定 在文檔載入完成後,可以使 ...
  • 不多說,直接開始吧 // ES6之前常用寫法 for(var i = 0;i<10;i++){ /閉包寫法 (function(j){ var a = document.createElement("div"); a.innerHTML = j + " "; a.addEventListener(" ...
  • IE瀏覽器對於同一個URL只返回相同結果。因為,在預設情況下,IE會緩存ajax的請求結果。對於同一個URL地址,在緩存過期之前,只有第一次請求會真正發送到服務端。大多數情況下,我們使用ajax是希望實現局部刷新的,所以這就牽扯到一個改進的問題。 如果想每次都獲取到最新數據,我們只需保證每次傳入的U ...
  • 在微信開發中,寫過的一個簡單的音樂播放組件,記錄下。 music 音樂播放組件。 屬性 代碼 properties: { // 音樂路徑 music: { type: String, value: '', observer: function (newVal) { this._initMusic(n ...
  • this其實是一個Html 元素。 $this 只是個變數名,加$是為說明其是個jquery對象。 而$(this)是個轉換,將this表示的dom對象轉為jquery對象,這樣就可以使用jquery提供的方法操作。 先來看看JQuery中的 $() 這個符號,實際上這個符號在JQuery中相當於J ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...