React Native的基本使用

React Native 是一款使用JavaScript和React編寫(xiě)原生移動(dòng)應(yīng)用的框架,熟練使用React的開(kāi)發(fā)者可以很容易的使用React Native來(lái)開(kāi)發(fā)APP,本文介紹一下React Native的安裝和基本使用。

React Native 中文網(wǎng)

安裝

本文是在window環(huán)境下安裝的,其他環(huán)境請(qǐng)參考官方文檔。

1. 安裝必需軟件

  • Node (版本需大于等于 12)
  • Python2 (版本必須為 2.x(不支持 3.x))
  • JDK (版本必須是 1.8)

2. 安裝nrm,yarn

    npm install nrm -g      // 安裝nrm
    npx nrm use taobao      // 切換淘寶源
    npm install yarn -g     // 安裝yarn

3. 安裝Android Studio

  1. 下載安裝Android Studio
  2. 安裝過(guò)程中Custom選項(xiàng)先不勾選
  3. 安裝完成后在 Android Studio 的歡迎界面中點(diǎn)擊"Configure",然后點(diǎn)擊SDK Manager
  4. 在 SDK Manager 中選擇"SDK Platforms"選項(xiàng)卡,然后在右下角勾選"Show Package Details"。展開(kāi)Android 9 (Pie)選項(xiàng),確保勾選了下面這些組件:
image
  1. 然后點(diǎn)擊"SDK Tools"選項(xiàng)卡,同樣勾中右下角的"Show Package Details"。展開(kāi)"Android SDK Build-Tools"選項(xiàng),確保選中了 React Native 所必須的28.0.3版本。你可以同時(shí)安裝多個(gè)其他版本。

  2. 配置 ANDROID_HOME 環(huán)境變量

React Native 需要通過(guò)環(huán)境變量來(lái)了解你的 Android SDK 裝在什么路徑,從而正常進(jìn)行編譯。
打開(kāi)控制面板 -> 系統(tǒng)和安全 -> 系統(tǒng) -> 高級(jí)系統(tǒng)設(shè)置 -> 高級(jí) -> 環(huán)境變量 -> 新建,創(chuàng)建一個(gè)名為ANDROID_HOME的環(huán)境變量(系統(tǒng)或用戶變量均可),指向你的 Android SDK 所在的目錄(具體的路徑可能和下圖不一致,請(qǐng)自行確認(rèn))

image

SDK 默認(rèn)是安裝在下面的目錄:

c:\Users\你的用戶名\AppData\Local\Android\Sdk

你可以在 Android Studio 的"Preferences"菜單中查看 SDK 的真實(shí)路徑,具體是Appearance & Behavior → System Settings → Android SDK。

  1. 把一些工具目錄添加到環(huán)境變量 Path 中

打開(kāi)控制面板 -> 系統(tǒng)和安全 -> 系統(tǒng) -> 高級(jí)系統(tǒng)設(shè)置 -> 高級(jí) -> 環(huán)境變量,選中Path變量,然后點(diǎn)擊編輯。點(diǎn)擊新建然后把這些工具目錄路徑添加進(jìn)去:platform-tools、emulator、tools、tools/bin

%ANDROID_HOME%\platform-tools
%ANDROID_HOME%\emulator
%ANDROID_HOME%\tools
%ANDROID_HOME%\tools\bin

4. 創(chuàng)建項(xiàng)目

找到你需要?jiǎng)?chuàng)建項(xiàng)目的目錄運(yùn)行

    npx react-native init myApp

Windows 用戶請(qǐng)注意,請(qǐng)不要在某些權(quán)限敏感的目錄例如 System32 目錄中 init 項(xiàng)目!會(huì)有各種權(quán)限限制導(dǎo)致不能運(yùn)行!

5. 下載木木模擬器

6. 由于第一次運(yùn)行時(shí)需要下載大量編譯依賴,這里建議使用阿里云的maven鏡像

修改 android/build.gradle

allprojects {
    repositories {
        mavenLocal()
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 
        ....
}

7. 連接模擬器

木木模擬器默認(rèn)端口為 7555

項(xiàng)目根目錄運(yùn)行

    adb connect 127.0.0.1:7555

連接成功會(huì)有提示

8. 運(yùn)行項(xiàng)目

在你的項(xiàng)目目錄中運(yùn)行yarn android 或者yarn react-native run-android

第一次運(yùn)行耗時(shí)較長(zhǎng)

基本使用

入門Hello World

編輯App.js

import React, { Component } from 'react';
import { Text, View } from 'react-native';

export default class HelloWorldApp extends Component {
  render() {
    return (
        <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
          <Text>Hello, world!</Text>
        </View>
    );
  }
}

React Native 看起來(lái)很像 React,只不過(guò)其基礎(chǔ)組件是原生組件而非 web 組件。

組件

一個(gè) App 的最終界面,其實(shí)也就是各式各樣的組件的組合。組件本身結(jié)構(gòu)可以非常簡(jiǎn)單——唯一必須的就是在render方法中返回一些用于渲染結(jié)構(gòu)的 JSX 語(yǔ)句。

  • 核心組件
原生組件 安卓 IOS HTML 描述
<View> <ViewGroup> <UIView> 非滾動(dòng)<div> 一個(gè)支持Flexbox,樣式,一些觸摸處理和輔助功能控件布局的容器
<Text> <TextView> <UITextView> <p> 顯示,設(shè)置樣式和嵌套文本字符串,甚至處理觸摸事件
<Image> <ImageView> <UIImageView> <img> 顯示不同類型的圖像
<ScrollView> <ScrollView> <UIScrollView> <div> 通用滾動(dòng)容器,可以包含多個(gè)組件和視圖
<TextInput> <EditText> <UITextField> <input> 允許用戶輸入文本
  • 文本輸入框組件

TextInput是一個(gè)允許用戶輸入文本的基礎(chǔ)組件。它有一個(gè)名為onChangeText的屬性,此屬性接受一個(gè)函數(shù),而此函數(shù)會(huì)在文本變化時(shí)被調(diào)用。另外還有一個(gè)名為onSubmitEditing的屬性,會(huì)在文本被提交后(用戶按下軟鍵盤(pán)上的提交鍵)調(diào)用。

  • 觸摸組件(Button)
<Button onPress={()=>alert("你好世界")} title="確定" color="#f30"></Button>

其中onPress是回調(diào)函數(shù),title是按鈕上顯示的文字,color是按鈕顏色;

也可以作為警告框,擁有多個(gè)選項(xiàng),從而彈出不同內(nèi)容:

<Button 
    onPress={()=>Alert.alert("小胖別吃了好嗎?","你已經(jīng)160斤了!",[
        {text:'不行',onPress:()=>alert("小胖:不行我餓")},
        {text:'好吧',onPress:()=>alert("小胖:好吧我不吃了")},
        {text:'難過(guò)',onPress:()=>alert("小胖:我是單身狗,胖點(diǎn)怕啥")},
    ])}
    title="詢問(wèn)小胖"
    color="blue">
</Button>

可以看到我們?cè)O(shè)置了三個(gè)選項(xiàng),每一項(xiàng)都會(huì)彈出不同的內(nèi)容,內(nèi)容也是自己設(shè)置的;

  • 觸摸組件(Touchable 系列組件)

這個(gè)組件的樣式是固定的。所以如果它的外觀并不怎么搭配你的設(shè)計(jì),那就需要使用TouchableOpacity或是TouchableNativeFeedback組件來(lái)定制自己所需要的按鈕

  1. 使用TouchableHighlight來(lái)制作按鈕或者鏈接。注意此組件的背景會(huì)在用戶手指按下時(shí)變暗。

  2. 在 Android 上還可以使用TouchableNativeFeedback,它會(huì)在用戶手指按下時(shí)形成類似墨水漣漪的視覺(jué)效果。

  3. TouchableOpacity會(huì)在用戶手指按下時(shí)降低按鈕的透明度,而不會(huì)改變背景的顏色。

  4. 如果想在處理點(diǎn)擊事件的同時(shí)不顯示任何視覺(jué)反饋,則需要使用TouchableWithoutFeedback

  5. 某些場(chǎng)景中可能需要檢測(cè)用戶是否進(jìn)行了長(zhǎng)按操作。可以在上面列出的任意組件中使用onLongPress屬性來(lái)實(shí)現(xiàn)。

  • 滾動(dòng)視圖

ScrollView是一個(gè)通用的可滾動(dòng)的容器,可以在其中放入多個(gè)組件和視圖,而且這些組件并不需要是同類型的。ScrollView 不僅可以垂直滾動(dòng),還能水平滾動(dòng)(通過(guò)horizontal屬性來(lái)設(shè)置)。
ScrollView適合于顯示數(shù)量不多的滾動(dòng)元素。放置在ScrollView中的所有組件都會(huì)被渲染

  • 長(zhǎng)列表

FlatList組件用于顯示一個(gè)垂直的滾動(dòng)列表,其中的元素之間的結(jié)構(gòu)近似而僅數(shù)據(jù)不同。
FlatList和ScrollView不同的是,F(xiàn)latList并不立即渲染所有元素,而是優(yōu)先渲染屏幕上可見(jiàn)的元素。
FlatList組件必須的兩個(gè)屬性是data和renderItem。data是列表的數(shù)據(jù)源,而renderItem則從數(shù)據(jù)源中逐個(gè)解析數(shù)據(jù),然后返回一個(gè)設(shè)置好格式的組件來(lái)渲染。
例如渲染數(shù)據(jù):

<FlatList
    keyExtractor={item=>item.ID}
    data={this.state.movies}
    numColumns={3}   //一行顯示3個(gè)
    columnWrapperStyle={styles.row} //增加下方寫(xiě)的樣式
    renderItem={({item})=>{return(
        <View style={{marginTop:20}} key={item.ID}>
        <Image 
          style={{width:135,height:160}} 
          source={{uri:item.defaultImage}}>
        </Image>
        <Text style={{marginTop:5,textAlign:"center"}}>{item.MovieName}</Text>
        </View>
    )}}
/>

/*
flatList長(zhǎng)列表組件,
keyExtractor是key抽取
data數(shù)據(jù)指定
numColumns行的數(shù)量,
renderItem列的渲染
columnWrapperStyle行的樣式指定
*/

更多組件請(qǐng)參考官方文檔

Props

render() {
    let pic = {
      uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
    };
    return (
      <Image source={pic} style={{width: 193, height: 110}} />
    );
}

{pic}外圍有一層括號(hào),我們需要用括號(hào)來(lái)把pic這個(gè)變量嵌入到 JSX 語(yǔ)句中。括號(hào)的意思是括號(hào)內(nèi)部為一個(gè) js 變量或表達(dá)式,需要執(zhí)行后取值。

自定義的組件也可以使用props。通過(guò)在不同的場(chǎng)景使用不同的屬性定制,可以盡量提高自定義組件的復(fù)用范疇。只需在render函數(shù)中引用this.props,然后按需處理即可。下面是一個(gè)例子:

import React, { Component } from 'react';
import { Text, View } from 'react-native';

class Greeting extends Component {
  render() {
    return (
      <View style={{alignItems: 'center', marginTop: 50}}>
        <Text>Hello {this.props.name}!</Text>
      </View>
    );
  }
}

export default class LotsOfGreetings extends Component {
  render() {
    return (
      <View style={{alignItems: 'center'}}>
        <Greeting name='Rexxar' />
        <Greeting name='Jaina' />
        <Greeting name='Valeera' />
      </View>
    );
  }
}

最終3個(gè)名字會(huì)被依次輸出。

State

React Native使用兩種數(shù)據(jù)來(lái)控制一個(gè)組件:props和state。props是在父組件中指定,而且一經(jīng)指定,在被指定的組件的生命周期中則不再改變。對(duì)于需要改變的數(shù)據(jù),我們需要使用state。

一般來(lái)說(shuō),需要在class中聲明一個(gè)state對(duì)象,然后在需要修改時(shí)調(diào)用setState方法。典型的場(chǎng)景是在接收到服務(wù)器返回的新數(shù)據(jù),或者在用戶輸入數(shù)據(jù)之后。你也可以使用一些“狀態(tài)容器”比如Redux來(lái)統(tǒng)一管理數(shù)據(jù)流。
每次調(diào)用setState時(shí),BlinkApp 都會(huì)重新執(zhí)行 render 方法重新渲染。

注意

  • 一切界面變化都是狀態(tài)state變化
  • state的修改必須通過(guò)setState()方法
  • this.state.likes = 100; // 這樣的直接賦值修改無(wú)效!
  • setState 是一個(gè) merge 合并操作,只修改指定屬性,不影響其他屬性
  • setState 是異步操作,修改不會(huì)馬上生效

樣式的書(shū)寫(xiě)

行內(nèi)樣式

 <View>
           <Text style={[styles.red,styles.big]}>我是內(nèi)聯(lián)樣式文本</Text>
           <Text style={{fontWeight:"bold"}}>我是行內(nèi)樣式文本</Text>
           <Text style={{...styles.big,color:"yellow", fontStyle:"italic"
}}>我是內(nèi)聯(lián)+行內(nèi)混合樣式文本</Text>
</View>

在render函數(shù)外部定義樣式

const styles = StyleSheet.create({
  center:{justifyContent:"center",alignItems:"center"},
  row:{flexDirection:"row",justifyContent:"space-around"},
  col:{flex:1,height:180},
  big:{fontSize:48},
  red:{color:"#f30"}
});

網(wǎng)絡(luò)請(qǐng)求

一般長(zhǎng)列表的數(shù)據(jù)都是通過(guò)網(wǎng)絡(luò)請(qǐng)求獲取的;然后渲染到頁(yè)面;
傳統(tǒng)方式如下:

fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',   //請(qǐng)求方式
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',    //請(qǐng)求頭
  },
  body: 'key1=value1&key2=value2',     //請(qǐng)求參數(shù)
});

上面的示例演示了如何發(fā)起請(qǐng)求。很多情況下,還需要處理服務(wù)器回復(fù)的數(shù)據(jù)。網(wǎng)絡(luò)請(qǐng)求天然是一種異步操作;異步的意思是應(yīng)該提取方法會(huì)返回一個(gè)Promise,這種模式可以簡(jiǎn)化異步風(fēng)格的代碼;
如下所示:

function getMoviesFromApiAsync() {   //獲取電影xx的方法,自己創(chuàng)建的
  return fetch('https://facebook.github.io/react-native/movies.json')   //接口網(wǎng)站
    .then((response) => response.json())    //將請(qǐng)求到的數(shù)據(jù)轉(zhuǎn)為json格式
    .then((responseJson) => {
      return responseJson.movies;   //請(qǐng)求成功返回?cái)?shù)據(jù)
    })
    .catch((error) => {
      console.error(error);    //請(qǐng)求失敗,輸出錯(cuò)誤
    });
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容