初學react native基礎(組件、API、插件、樣式、佈局)

React Native

React Native 看起來很像 React,只不過其基礎組件是原生組件而非 web 組件。要理解 React Native 應用的基本結構,首先需要了解一些基本的 React 的概念,比如 JSX 語法、組件、state狀態以及props屬性。如果你已經瞭解了 React,那麼還需要掌握一些 React Native 特有的知識,比如原生組件的使用。這篇教程可以供任何基礎的讀者學習,不管你是否有 React 方面的經驗。

TextInput

通過 value 屬性指定文本內容, 通過 onChangeText 屬性監聽文本的變化事件

從TextInput談綁定this傳參數

我們在使用TextInput發現每次輸入完後;輸入的都無效;這是因爲要改變沒有更改數據源

  1. 使用箭頭函數實現;這樣不會改變this的指向
import React from 'react';
import { View,  TextInput, StyleSheet } from 'react-native';
export default class ElseStudy extends React.Component{
    constructor(props){
        super(props)
        this.state = {myText:'Useless Placeholder'}
    }
    render(){
        return (
            <View>
                <TextInput 
                    value={this.state.myText} 
                    onChangeText={(text)=>this.changeTextHandle(text)}
                    ></TextInput>
            </View>
        )
    }
    changeTextHandle(newText){
        this.setState({
            myText:newText
        })
    }
}
  1. 當然代碼少,我們可以不用聲明一個函數,直接寫在{}
        return (
            <View>
                <TextInput 
                    value={this.state.myText} 
                    onChangeText={(myText)=>this.setState({myText})}
                    ></TextInput>
            </View>
        )
  1. 使用bind改變this的指向
    render(){
        return (
            <View>
                <TextInput 
                    value={this.state.myText} 
                    onChangeText={this.changeTextHandle.bind(this)}
                    ></TextInput>
            </View>
        )
    }
    changeTextHandle(newText){
        this.setState({
            myText:newText
        })
    }

ScrollView

  1. 默認情況下, 超出屏幕的內容是看不到的, 不像瀏覽器環境下會自動添加滾動條
  2. 如果需要滾動, 可以使用這個組件把要相應的內容包裹起來, 被包裹的內容就會處於滾動條中
  3. 滾動的過程中,可以通過onScroll綁定回調,每幀最多調用一次回調
import React from 'react';
import { StyleSheet, Text, View,ScrollView } from 'react-native';
export default class ScrollViewStudy extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            list: ["red", "yellow", "pink", "orange", "blue", "skyblue"]
        }
    }
    render(){
        return (
            <View>
            {
                this.state.list.map(color => (
                    <View 
                        key={color} 
                        style={{backgroundColor: color, width: 300, height: 180}}>
                        <Text>{color}</Text>
                    </View>
                ))
            }
            </View>
        )
    }
}

我們使用View包裹着每個View組件;發現手機只顯示中間部分的組件;並不能滾動;我們可以使用scrollView進行包裹

    <ScrollView>
            {
                this.state.list.map(color => (
                    <View 
                        key={color} 
                        style={{backgroundColor: color, width: '100%', height: 180}}>
                        <Text>{color}</Text>
                    </View>
                ))
            }
            </ScrollView>
ScrollView實現輪播
import React from 'react'
import { StyleSheet, View,ScrollView,Text } from 'react-native';
const Dimensions = require('Dimensions');
const screenSize = Dimensions.get("window");
export default class Lunbotu extends React.Component{
    constructor(props){
        super(props)
        this.state = {
            list: ["red", "yellow", "pink", "orange"]
        }
    }
    getList(){
        return this.state.list.map((color,i) => (
            <View 
            key={i}
            style={[styles.swipeItem, {backgroundColor: color}]}
            >
            <Text>i</Text>
            </View>
        ))
    }
    render(){
        return (
            <ScrollView
            horizontal={ true }
            pagingEnabled={ true }
            showsHorizontalScrollIndicator={ false }
            >
            
                {this.getList()}
            </ScrollView>
        )
    }
}
const styles = StyleSheet.create({
    swipeItem:{
        width: screenSize.width,
        height: 200
    }
})
  1. Dimensions可以動態獲取屏幕的寬高,用這個寬高我們可以根據需求自己計算。使用它的時候,主要是因爲我們不能確定父盒子的寬高與屏幕的關係
  2. horizontal屬性可設置列表水平排列,pagingEnabled屬性能夠讓列表一頁一頁切換,showsHorizontalScrollIndicator屬性控制滾動條顯示隱藏
  3. 其實我們只是讓每一個子元素(輪播容器swiper-item)水平排列,請求去掉滾動條;然後在滑動一下顯示一頁即可

FastList

高性能的簡單列表組件

使用方法

import React, { Component } from "react";
import { StyleSheet, View, Text, FlatList } from 'react-native';
export default class FlatListTest extends Component {
    render() {
        return (
            <View>
                <FlatList
                    data={[
                        {key: 'Devin'},
                        {key: 'Jackson'},
                        {key: 'James'},
                        {key: 'Joel'},
                        {key: 'John'},
                        {key: 'Jillian'},
                        {key: 'Jimmy'},
                        {key: 'Julie'}
                    ]}
                    renderItem={(e) => <Text style={styles.item}>{e.index + ":" + e.item.key}</Text>}
                />
            </View>
        );
        
    }
}

const styles = StyleSheet.create({
    item: {
        padding: 10,
        fontSize: 18,
        height: 44,
    },
});

ActivityIndicator

  1. 展示一個小圓形的loading
  2. 通過屬性 animating 控制顯示隱藏, color 設置顏色
  3. 我們可以用它來做數據的加載等等…
import React, { Component } from "react";
import { StyleSheet, View, Text, ActivityIndicator } from 'react-native';
export default class FlatListTest extends Component {
    render(){
        return (
            <ActivityIndicator
            animating={true}
            color="green" 
            size="large" />
        )
    }
}

觸控系列組件

在需要捕捉用戶點擊操作時,可以使用Touchable開頭的一系列組件。這些組件通過onPress屬性設置點擊事件的處理函數。當在本組件上按下手指並且擡起手指時也沒有移開到組件外時,此函數會被調用。Touchable組件最大的特點是附帶反饋效果。

import React from 'react'
import { 
    StyleSheet, 
    View, 
    Image,
    Text, 
    TouchableHighlight, 
    TouchableOpacity, 
    TouchableNativeFeedback 
} from 'react-native';
export default class TouchableStudy extends React.Component{
    render(){
        return (
            <View>
                <TouchableOpacity
                activeOpacity={0.5} 
                >
                    <Text style={styles.baseFont}>透明按鈕</Text>
                </TouchableOpacity>
                <TouchableHighlight
                underlayColor="#fal33j"
                    activeOpacity={0.5}>
                    <Text style={styles.baseFont}>高亮按鈕</Text>
                </TouchableHighlight>
                <TouchableNativeFeedback 
                    background={TouchableNativeFeedback.SelectableBackground()}
                    >
                    <View style={styles.base}>
                        <Text style={styles.baseFont}>原生按鈕</Text>
                    </View>
                </TouchableNativeFeedback>
            </View>
        )
    }
}
const styles = StyleSheet.create({
    base: {
        margin: 10,
        width: 300,
        height: 100,
        borderRadius: 5,
        backgroundColor: 'green',
        justifyContent: 'center',
    },
    baseFont: {
        color: "orange",
        textAlign: "center",
        lineHeight: 50
    }
})

使用原生狀態渲染反饋效果,比如漣漪,只能放置一個view子組件;效果有三個可選方法:SelectableBackground、SelectableBackgroundBorderless、Ripple(color)

Alter

import React from 'react'
import { 
    Alert,
    Button,
} from 'react-native';
export default class AlertStudy extends React.Component{
    alertHandle(){
        Alert.alert(
            'Alert Title',
            'My Alert Msg',
            [
              {text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
              {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
              {text: 'OK', onPress: () => console.log('OK Pressed')},
            ],
            { cancelable: false }
          )

    }
    render(){
        return(
            <Button title="點我彈框" onPress={()=>this.alertHandle()}></Button>
        )
    }
}

看界面一下子就能知道它的各個含義: 配置一個按鈕是確定,兩個按鈕是取消與確定,三個按鈕是稍後再試、取消與確定
結果

Dimensions

const Dimensions = require('Dimensions');
const screenSize = Dimensions.get("window");

const styles = StyleSheet.create({
    container: {
        width: screenSize.width,
        height: screenSize.height
    }
});

本模塊用於獲取設備屏幕的寬高。儘管尺寸信息立即就可用,但它可能會在將來被修改(譬如設備的方向改變),所以基於這些常量的渲染邏輯和樣式應當每次render之後都調用此函數,而不是將對應的值保存下來。

Picker

本組件可以在iOS和Android上渲染原生的選擇器(Picker)

import React from 'react'
import {View,Text,StyleSheet,Picker} from 'react-native'
export default class Products extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            language:'react',
            pickerOptions:[
                {
                    id:1,
                    value:'vue'
                },
                {
                    id:2,
                    value:'react'
                },
                {
                    id:3,
                    value:'angular'
                }
            ]
        }
    }
    render(){
        return (
          <View style={styles.container}>
            <Text>個人信息頁面</Text>
            <Picker
                selectedValue={this.state.language}
                style={{ height: 50, width: 200,backgroundColor:'hotpink',marginVertical:20 }}
                onValueChange={(itemValue, itemIndex) => this.setState({language: itemValue})}>
                {
                    this.state.pickerOptions.map((item)=>{
                        return <Picker.Item label={item.value} value={item.value} key={item.id} />
                    })
                }
            </Picker>
          </View>
        )
    }
}
const styles = StyleSheet.create({
    container:{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
})

選擇狀態

Slider

用於選擇一個範圍值的組件,一個滑動塊。
在這裏插入圖片描述

  1. 引入我們的滑塊和所需要的Alert方法
import {View,Text,StyleSheet,Picker,Slider,Alert} from 'react-native'
  1. 在render生命鉤子裏面渲染該組件
            <Slider
                style={styles.slider}
                maximumValue={100}
                minimumValue={0}
                minimumTrackTintColor='hotpink'
                step={1}
                maximumTrackTintColor='red'
                onSlidingComplete={this.completeHandler}
            >
            </Slider>
  1. 樣式
const styles = StyleSheet.create({
    slider:{
        width: 300
    }
})
  1. 方法
    completeHandler= (val)=>{
        Alert.alert(
            this.state.language+'基礎分爲',
            val+'分',
            [
              {text: 'Ask me later'},
              {text: 'Cancel'},
              {text: 'OK'},
            ],
            { cancelable: false }
          )
    }
  1. onSlidingComplete效果:用戶鬆開滑塊的時候調用此回調,無論值是否變化。回調值爲當前值。
    效果

樣式

StyleSheet

  1. 所有RN中的樣式都必須用這個Api創建
  2. 所有樣式名稱都必須是駝峯命名
  3. RN中所有的組件默認display屬性都是flex,而且主軸方向是column
  4. 每個元素可以通過數組設置多種樣式,如果遇到相同的樣式,後面樣式的優先級大於前面

RN的盒子模型

  1. 在RN中的元素同樣擁有盒子模型:寬高、內邊距、邊框、外邊距。
  2. 需要注意在RN中的樣式大小不需要單位,同時沒有css的複合樣式,比如border、background、font,在RN中border寬度、顏色、圓角等樣式需要一個一個設置,background和font也一樣。
  3. 關於padding與margin,在css中可以賦予多個值來設置四邊不一樣的大小,在RN中只能給定一個值,指定相同的大小,如果四邊大小不一樣,就需要按照方向一個一個設置。同時RN也提供了paddingHorizontal、marginHorizontal、paddingVertical、marginVertical同時設置左右和上下兩個方向的值。
  4. 另外補充一下,在設置字體時,Android內建的有這麼幾個: normal、serif、monospace
import React, { Component } from "react";
import { StyleSheet, View, Text } from 'react-native';
export default class LayoutStudy extends React.Component{
    render(){
        return (
            <View style={styles.container}>
                <View style={styles.box}>
                    <Text>內容</Text>
                </View>
            </View>
        )
    }
}
const styles = StyleSheet.create({
    container: {
        width: 300,
        height: 300,
        backgroundColor: "blue"
    },
    box:{
        width: 200,
        height: 200,
        backgroundColor: "red",
        paddingHorizontal: 50,
        paddingVertical: 50,
        borderWidth: 30,
        borderColor: "yellow",
        margin: 30
    }
})

盒子模型

RN的伸縮佈局

  1. ReactNative中組件默認採用flex彈性佈局,使用flex可以使其在可利用的空間中動態地擴張或收縮。
  2. ReactNative中的flex工作原理和web上的CSS基本一致,當然也存在少許差異。首先是默認值不同:flexDirection的默認值是column而不是row,也就是元素縱向排列;而flex也只能指定一個數字值
import React, { Component } from "react";
import { StyleSheet, View, Text } from 'react-native';
export default class FlexLayout extends Component{
    render(){
        return (
            <View>
                <View>
                    <View><Text>123</Text></View>
                    <View><Text>456</Text></View>
                </View>
                {/* 改爲橫向排列 */}
                <View style={styles.row}>
                    <View><Text>123</Text></View>
                    <View><Text>456</Text></View>
                </View>
            </View>
        )
    }
}
const styles = StyleSheet.create({
    row:{
        flexDirection: 'row'
    }
})

結果顯示

fetch

React Native 提供了和 web 標準一致的Fetch API,用於滿足開發者訪問網絡的需求。如果你之前使用過XMLHttpRequest(即俗稱的 ajax)或是其他的網絡 API,那麼 Fetch 用起來將會相當容易上手。這篇文檔只會列出 Fetch 的基本用法,並不會講述太多細節,你可以使用你喜歡的搜索引擎去搜索fetch api關鍵字以瞭解更多信息。
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
發送請求獲取數據

import React, { Component } from "react";
import { View, Text } from 'react-native';
export default class AjaxStudy extends Component{
    render(){
        return (
            <View>
                <Text>fetch的使用</Text>
            </View>
        )
    }
    componentWillMount(){
        fetch('http://www.liulongbin.top:3005/api/getprodlist')
        .then((response) => response.json())
        .then((responseJson) => {
            console.log(responseJson);
        })
        .catch((error) => {
            console.error(error);
        });
    }
}

結果如圖

第三方插件

react-native-swiper

這是一個可實現典型的輪播效果或翻頁效果插件,該插件只提供了一個組件Swiper,全部功能由該組件提供。該插件在內部對android與ios系統提供了不同的實現方式,如果是android系統才採用ViewPagerAndroid組件實現,ios系統則採用ScrollView實現。

  • 需要注意,Swiper組件的高度依賴與父元素,所以在使用時嵌套一個View標籤控制Swiper展示高度
  • 另外該庫的源碼使用了一個叫Arial的字體,模擬器中可以沒有這個字體導致報錯,可以修改爲normal、serif、monospace中的任意一個字體,或者刪除該樣式也可以。
    github react-native-swiper
    安裝: yarn add react-native-swiper -S
import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View
} from 'react-native';

import Swiper from 'react-native-swiper';

export default class SwiperTest extends Component {
  render(){
    let height = this.props.height || 200;

    return (
        <View style={[styles.wrapper, {height: height}]}>
            {/* showsButtons控制左右箭頭顯示,autoplay控制自動輪播 */}
            <Swiper showsButtons={true} autoplay={true}>
                <View style={[styles.item, styles.item1]}>
                    <Text style={styles.text}>Banner one</Text>
                </View>
                <View style={[styles.item, styles.item2]}>
                    <Text style={styles.text}>Banner two</Text>
                </View>
                <View style={[styles.item, styles.item3]}>
                    <Text style={styles.text}>Banner three</Text>
                </View>
            </Swiper>
        </View>
    );
  }
}

const styles = StyleSheet.create({
    wrapper: {
        marginTop: 24
    },
    item: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
    item1: {
        backgroundColor: '#9DD6EB',
    },
    item2: {
        backgroundColor: '#97CAE5',
    },
    item3: {
        backgroundColor: '#92BBD9',
    },
    text: {
        color: 'red',
        fontSize: 30,
        fontWeight: 'bold',
    }
});

如圖所示

react-navigation(更)

在 web 瀏覽器中, 你可以使用 (<a>) 標籤作爲錨點,鏈接到不同的頁面。 當用戶單擊某個鏈接時, 該 URL 就會被推送到瀏覽器歷史記錄堆棧。 當用戶點擊返回按鈕時, 瀏覽器會從歷史堆棧頂部刪除正在訪問的頁面, 因此當前頁現在就成了以前訪問過的頁面。 React Native沒有像Web瀏覽器那樣的內置全局歷史堆棧的想法 – 這就是 React Navigation 存在的意義

  1. 通常我們開發的App是由多個頁面構成的,那麼我們就需要一種或多種方式去管理這些頁面,在Web開發中,比較常見的管理方式有:Tab欄單頁嵌多內容,或者路由管理多頁面切換。
  2. react-navigation便是實現這種需求的RN插件,同時它還是官方推薦使用的第三方導航插件,可實現單頁多內容切換,也可以實現路由跳轉。
  3. react-navigation提供了幾種不同類型或者效果的導航組件,每個組件都由對應的工廠函數來創建,這些工廠函數在調用時通常都需要兩個參數,第一個參數統一爲路由配置對象,第二個參數則是一個個性化的配置對象,不同組件的配置項存在差異。
使用
# 安裝兩套包
yarn add react-navigation
yarn add react-native-gesture-handler

先學到這裏,持續更(前端交流羣749539640)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章