《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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...