1. 程式人生 > >React Native佈局實踐:開發京東客戶端首頁(四)——首頁功能按鈕及控制元件封裝

React Native佈局實踐:開發京東客戶端首頁(四)——首頁功能按鈕及控制元件封裝

從我寫第一篇React Native文章以來,我們幾乎是把所有的程式碼都放在一個js檔案中實現的,隨著工程複雜度的增加,各種自定義控制元件的程式碼就和業務邏輯程式碼耦合嚴重,這篇文章就來解決這一問題,讓我們一起來學習控制元件封裝的方法。

1.明確需求

首頁功能按鈕由一個圖片、一行文字,縱向排列組成,當點選一個控制元件時,同時觸發點選事件。


目前我們需要的是8個這樣的控制元件,如果我們為每個控制元件都寫一堆JSX,那麼程式碼就會很混亂,而如果我們在當前的JS檔案中編寫一個方法(如_renderButton()),專門用於生產這樣的控制元件,雖然可以少寫一些程式碼,但容易和其他業務邏輯程式碼耦合在一起,這樣不便於維護和更新,所以,最好的辦法是把這樣一種組合檢視,封裝為控制元件,並單獨寫在一個JS檔案中,此時,我們可以確定一下這個控制元件的屬性:

①圖片:用於展示的Icon,暫定為來自本地,為number型別

②標題:展示的標題,一串文字,為String型別

③Tag:用於區分按鈕,為String型別

④回撥函式:用於在點選該按鈕時進行回撥,為Function型別(回撥時應該考慮回傳Tag)

2.設計控制元件樣式

首先我們在home目錄中新建一個js檔案,名為MenuButton.js,引入我們需要的Image、Text、View以及其他的常用庫,Component、StyleSheet,同時建立一個可匯出的類,如下圖所示

 

接著,我們可以根據我們對按鈕結構的分析,以及掌握的尺寸資訊,在render方法中設計控制元件的佈局,並建立控制元件的樣式,由於這個控制元件的結構很簡單,所以這裡直接給出程式碼,首先是render函式:

    render() {
        return (
            <TouchableWithoutFeedback>
                <View style={{alignItems:'center',flex:1}}>
                    <Image style={styles.iconImg} />
                    <Text>Example Text</Text>
                </View>
            </TouchableWithoutFeedback>
        );
    }

下來是樣式:

const styles = StyleSheet.create({
    iconImg: {
        width: 38,
        height: 38,
        marginBottom: 2
    }
});
這裡我們可以看到,在render函式中,我並沒有為Image指定source,Text也只是加了一串示例文字,不要著急,下面就是控制元件封裝的關鍵!

3.宣告控制元件屬性

當我們的控制元件佈局已經建立完成以後,其中的問題就是,如何把我們需要的值,包括icon圖片、title文字、回撥函式等內容傳到當前控制元件中呢?

這裡的關鍵就在於:控制元件屬性的宣告

為什麼要進行屬性宣告?

原因很簡單,拿Image控制元件來說,我們常常用下面的方式指定Image的樣式、圖片等內容

<Image style={...} source={...} />
想要讓自己構建的控制元件也能像上沒的方式那樣進行定義,就必須使用屬性

根據我們之前的分析,主頁功能按鈕的屬性可以這樣進行宣告,將如下程式碼寫在建構函式之前即可:

    static propTypes = {
        renderIcon: PropTypes.number.isRequired,  // 圖片,加入.isRequired即為比填項
        showText: PropTypes.string,  // 顯示標題\文字
        tag: PropTypes.string,  // Tag
        onClick: PropTypes.func  // 回撥函式
    };

對於PropTypes的使用,需要在檔案頭部,和Text、View這些一起,引入PropTypes即可。

接著,我們需要將屬性內容進行處理,但在處理之前,需要介紹一下這些屬性是怎麼獲得的。

其實,從本質上講,在JSX中,利用<>宣告一個控制元件,在將其轉換為真正的Native控制元件時,會首先呼叫其對應的JS原始碼,而JS原始碼首先會執行帶有props的建構函式,此建構函式會將我們在JSX中寫到的屬性,存在當前類的props中。


如上圖所示,這種過程類似於在0.16之前使用ES5的語法中,呼叫getDefaultProps方法,進行初始化。並且,我們在JSX中寫入的屬性,會以鍵值對的形式儲存,所以我們在以後的使用中,即可從this.props中取到在JSX中寫到的屬性了。
由於JavaScript語法的自由性,其實這些屬性不在static propTypes中宣告,只要JSX中寫了,後面也是可以取到的,但是為了可讀性和安全性,建議大家還是在static propTypes中宣告清楚!

4.使用屬性

首先,我們先在render函式中,為TouchableWithoutFeedback控制元件新增onPress事件,為Image新增source,為Text新增顯示的文字,如下程式碼:
    render() {
        return (
            <TouchableWithoutFeedback onPress={this._onClick}>
                <View style={{alignItems:'center',flex:1}}>
                    <Image style={styles.iconImg} source={this.props.renderIcon}/>
                    <Text>{this.props.showText}</Text>
                </View>
            </TouchableWithoutFeedback>
        );
    }
為了安全,我們在當前類中加入了_onClick方法,用來進行回撥函式的具體操作,它的功能是保證在設定了回撥函式的情況下執行回撥,而未設定則不回撥:
    _onClick() {
        if (this.props.onClick) {   // 在設定了回撥函式的情況下
            this.props.onClick(this.props.showText, this.props.tag);  // 回撥Title和Tag
        }
    }
然而,由於需要使用this來獲取props,由於在ES6中,函式預設是不繫結this的,所以請一定在建構函式中對函式進行繫結,否則將無法取值
    constructor(props) {
        super(props);
        this._onClick = this._onClick.bind(this);  // 需要在回撥函式中使用this,必須使用bind(this)來繫結
    }
這樣一來,我們的控制元件封裝也就基本結束了,下來就可以在HomeScreen.js中使用了!

5.使用封裝好的控制元件

正如其他控制元件一樣,我們只需要將自己封裝的控制元件import進來,即可在render中使用了

import MenuButton from './MenuButton';
                <View style={styles.menuView}>
                    <MenuButton renderIcon={require('../images/home_icons/wdgz.png')}
                                showText={'我的關注'} tag={'wdgz'}
                                onClick={this._onMenuClick}/>
                    <MenuButton renderIcon={require('../images/home_icons/wlcx.png')}
                                showText={'物流查詢'} tag={'wlcx'}
                                onClick={this._onMenuClick}/>
                    <MenuButton renderIcon={require('../images/home_icons/cz.png')}
                                showText={'充值'} tag={'cz'}
                                onClick={this._onMenuClick}/>
                    <MenuButton renderIcon={require('../images/home_icons/dyp.png')}
                                showText={'電影票'} tag={'dyp'}
                                onClick={this._onMenuClick}/>
                </View>
這裡只給出第一行4個圖示的程式碼,完整程式碼請到我的Github上檢視:https://github.com/yuanguozheng/JdApp


好了,大功告成,在模擬器上看看程式執行效果吧:

 

相關推薦

React Native佈局實踐開發京東客戶——功能按鈕控制元件封裝

從我寫第一篇React Native文章以來,我們幾乎是把所有的程式碼都放在一個js檔案中實現的,隨著工程複雜度的增加,各種自定義控制元件的程式碼就和業務邏輯程式碼耦合嚴重,這篇文章就來解決這一問題,讓我們一起來學習控制元件封裝的方法。1.明確需求首頁功能按鈕由一個圖片、一行

React Native入門——佈局實踐開發京東客戶TabBar的構建

上篇文章講到構建京東客戶端首頁的搜尋欄,本篇我們一起來學習TabBar的構建。根據之前的調研,在構建TabBar的方式上,我推薦使用國外大神James Ide(https://github.com/ide)釋出在Exponent上的react-native-tab-navig

【Win 10 應用開發】UI Composition 劄記繪制圖形

圖形 package 記得 aml 3.5 平時 surf 繪圖 str 使用 Win 2D 組件,就可以很輕松地繪制各種圖形,哪怕你沒有 D2D 相關基礎,也不必寫很復雜的 C++ 代碼。 先來說說如何獲取 Win 2D 組件。很簡單,創建 UWP 應用項目後,你打開&

每日知識總結計劃java、android、react native、web框架、js、css、html、ajax

作為一名資訊系的學生,現在學的太多,忘得也快,但是實在不忍心辛苦理解的知識就這樣慢慢被自己忘記。 所有這篇帖子作為今天起(2018.10.16  17:32),記錄每天得知識總結首頁。 下面得帖子連結分為一個月為一個單位做記錄,每天的記錄就在當月的一個月的帖子上更新。 20

STM32開發筆記50STM32F4+DP83848乙太網通訊指南系列PHY配置

本章為系列指南的第四章,這一章將正式進入乙太網的配置和使用。首先我們關注一下PHY的配置,前面講到,我們的工程使用了開發板上的一顆DP83848晶片。 RMII和ADDR的確定 接下來我們來看開發板的原理圖: 通過電路原理圖可以看到接線方式是使用RMII介面模式接線的,因此接下來我

開發一個 Linux 偵錯程式Elves 和 dwarves

https://linux.cn/article-8719-1.html 到目前為止,你已經偶爾聽到了關於 dwarves、除錯資訊、一種無需解析就可以理解原始碼方式。今天我們會詳細介紹原始碼級的除錯資訊,作為本指南後面部分使用它的準備。 系列文章索引 隨著後面文章的釋出,這些連結會逐漸

無線客戶框架設計1前言、目錄,以及一些念念碎

接下來要說的一個系列,是一個完整的App應用所需要的企業級框架設計,是我這2年來在無線客戶端這個領域摸爬滾打的,總結沉澱的心得體會,中途吃了很多虧,走過很多彎路,加了很多班,一次又一次的重構,不斷的學習,才知道,哦,原來iOS要這麼做,原來Android要那麼做,然後回過頭來再看看我最熟悉的WP,哦,原來WP

無線 iphone客戶測試白皮書

同名 一次 消息推送 自動跳轉 資源 快速 簡單 通訊 一個數據庫 7 、 PUSH 測試 1) 檢查 push 消息是否按照指定的業務規則發送 2) 檢查不接受推送消息時,檢查用戶不會再接收到 push. 3) 如果用戶設置了免打擾的時間段,檢查在免打擾時間段內,用戶接收

廖雪峰網站學習python基礎知識—循環

con class strong 網站 python bre 計算 end hal 一、循環 1、for names = [‘Michal‘, ‘Bob‘, ‘tracy‘] for name in names: print(name) sum =

Spring Cloud Ribbon(客戶負載均衡)2

1.引數配置 對於Ribbon的引數配置通常有兩種方式:全域性配置以及指定客戶端配置: 全域性配置:ribbon.<key>=<value>格式進行配置即可。<key>代表了Ribbon客戶端配置的引數名,<value>代表了對應引數值。比

unity3D-----------socket客戶、伺服器簡單

利用socket簡單的實現,客戶端和伺服器之間的通訊。 客戶端: using UnityEngine; using System.Collections; using System.Text; using System.Net; using System.Net.Soc

oracle無客戶連線資料庫C#

前提: 1. 不安裝oracle的客戶端 2. 不需要配置ora檔案 3. C# 實現   既然是C#實現,當然就要去找oracle的連線庫了,主要有三種方式: 1. 微軟提供的System.Data.OracleClient已經過時了,不推薦使用了 2. Or

【pykafka】爬蟲篇python使用python連線kafka介紹

本人菜雞,最近還更新python的爬蟲系列,有什麼錯誤,還望大家批評指出! 該系列暫時總共有4篇文章,連線如下: 【python】爬蟲篇:python連線postgresql(一):https://blog.csdn.net/lsr40/article/details/83311860

標號2python(就業階段)——Linux系統命令1——《高階Linux命令命令選項的使用》

一、高階Linux命令及命令選項的使用 <1>重定向命令:> Linux允許將命令執行結果重定向到一個檔案,本應顯示在終端上的內容儲存到指定檔案中。 1、ls >> test.txt 輸出重定向則會追加到檔案的尾部。 2、ls > test.t

用Django框架開發一個簡單的企業網站

現在通過後臺可以新建文章分類,並且編輯儲存文章了;由於Django預設的大容量文字欄位是通過一個textarea作為輸入方式,所以我們還需要引入一個富文字編輯器,這裡我推薦KindEditor(http://kindeditor.net/demo.php),配置簡單,功能也齊全。 將下載好的

dubbo-php-framework的客戶api解析

從這篇,我們開始分析客戶端的側的流程,所謂客戶端就是指dubbo-php-frame框架中consumer端,我們結合demo來看看consumer的呼叫流程,下面程式碼路徑為dubbo-php-framework-master/demo/demo-consumer/serv

dubbo-php-framework的客戶api解析

這篇我們開始解析ProxyFactory的流程,這個類重點完成了客戶端生成代理的流程,其路徑為dubbo-php-framework-master/consumer/proxy/ProxyFactory.php,我們接著dubbo-php-framework的客戶端api解析

dubbo-php-framework的客戶api解析

這篇我們分析生成Proxy後的處理流程,接著前面一篇文章,我們可以看到有p2p和register模式,這兩種模式最大的區別是服務地址資訊從哪裡獲取,而proxy的處理流程卻是一直的。 public static function newProxyInstance($ser

PHP+MySQL開發小專案的集合筆記控制div的排列和p標籤,從另外表讀取加工資料並規定小數點位數

需求:HTML頁面增加註釋,div盒子控制曲線大小,多個盒子相互巢狀。具體資料從另外表內獲取。 HTML頁面更改: <!-- Morris chart - Sales --> <!-- Change! -->

ZooKeeper的Java客戶工具使用Curator

安裝 <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-client</artifactId> <vers