react native 基礎(chǔ)知識點(diǎn)

Hello World

react native 官方Hello world示例

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

class HelloWorldApp extends Component {
  render() {
    return (
      <Text>Hello world!</Text>
    );
  }
}

// 注意,這里用引號括起來的'HelloWorldApp'必須和你init創(chuàng)建的項(xiàng)目名一致
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);

我們從import開始來看這個程序:
第一行和第二行都是import xxx from 'xxxxx',這句話的意思大概就是從'xxxxx'文件中引入xxx ,import 語句是es6的內(nèi)容,關(guān)于es6的新特性可以看阮一峰老師的書,后邊的文件是一個js文件他只寫了文件名沒有跟上.js后綴,import和from 之間的內(nèi)容就是文件中定義的組件。
接下來看 下面class xxx extends Component{}這個看著有點(diǎn)像JAVA的類繼承語句,這也是es6的內(nèi)容Component是一切界面組件的根類實(shí)現(xiàn)界面組件必須要像上面一樣繼承此類,再看類內(nèi)的代碼render(){returun()}render的中文意思是渲染這就是組件的渲染函數(shù)return括號中的內(nèi)容就是界面上渲染的內(nèi)容
最后一句是AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);我們可以看到registerComponent函數(shù)有兩個參數(shù)第一個參數(shù)是一個字符串是項(xiàng)目的名字,第二參數(shù)是一個表達(dá)式=>符號也是es6的,內(nèi)容符號前面是參數(shù)列表符號后面是方法體,此語句的意思是以HelloWorldApp組件為根組件渲染這個項(xiàng)目,第二個參數(shù)可以替換為你自己想要的方法體,比如:AppRegistry.registerComponent('HelloWorldApp', () => MyApp);MyApp 是繼承自Component的組件。

Props(屬性)

第一個官方示例

大多數(shù)組件可以在創(chuàng)建的時候可以使用各種參數(shù)進(jìn)行定制,這些參數(shù)稱為屬性Props。下面看一個官方示例

import React, { Component } from 'react';
import { AppRegistry, Image } from 'react-native';

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

AppRegistry.registerComponent('Bananas', () => Bananas);

這是一段顯示一張圖片的代碼 其中的Image組件帶了兩個屬性分別為source 和style,source屬性用于指定圖片資源let是es6中新增加的關(guān)鍵字用于指定一個局部變量(詳細(xì)內(nèi)容看書),可以注意到source后面pic被一個{}包圍,這是在jsx代碼中插入js代碼的方式{}中可以寫js代碼。

獲取圖片的兩種方法

1、通過uri加載如上代碼所示:
let pic = { uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg' };
2、通過require
let pic = {require('./icon.png')}
require中的字符串是相對地址或者絕對地址,require()中的參數(shù)必須是一個字面量而不能是一個變量活常量

let path = './icon.png'
let pic = {require(path)} //這會報(bào)錯說找不到相應(yīng)的model
let pic = {require('./icon.png')}//正確

第二個示例

除了組件自帶的屬性我們也可以添加我們自己的屬性,示例如下:

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

class Greeting extends Component {
  render() {
    return (
      <Text>Hello {this.props.name}!</Text>
    );
  }
}

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

AppRegistry.registerComponent('LotsOfGreetings', () => LotsOfGreetings);

上面的代碼自定義了一個Greeting組件,使用了{this.props.name}去初始化組件,Text的組件中本來不包含這個屬性,是我們自己加的,我們無需任何聲明,只要在使用組件時加入這一個屬性即可。

狀態(tài)(state)

props和state共同控制了一個組件,props在父組件中指定,在指定組件的生命周期中不在改變。對于需要改變的數(shù)據(jù)我們使用state
一般來說,需要在constructor中初始化state,下面是一個實(shí)現(xiàn)文字閃爍效果的例子:

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

class Blink extends Component {
  constructor(props) {
    super(props);
    this.state = { showText: true };

    // 每1000毫秒對showText狀態(tài)做一次取反操作
    setInterval(() => {
      this.setState({ showText: !this.state.showText });
    }, 1000);
  }

  render() {
    // 根據(jù)當(dāng)前showText的值決定是否顯示text內(nèi)容
    let display = this.state.showText ? this.props.text : ' ';
    return (
      <Text>{display}</Text>
    );
  }
}

class BlinkApp extends Component {
  render() {
    return (
      <View>
        <Blink text='I love to blink' />
        <Blink text='Yes blinking is so great' />
        <Blink text='Why did they ever take this out of HTML' />
        <Blink text='Look at me look at me look at me' />
      </View>
    );
  }
}

AppRegistry.registerComponent('BlinkApp', () => BlinkApp);

樣式

在react native中,我們使用js來寫樣式。所有的核心組件都接受style屬性,這些樣式和css一樣唯一的區(qū)別就是,按照js的語法改用了駝峰寫法,background-color->backgroundColor
最簡單的寫法如下:
<Text style={{backgroundColor:'red',height:50,width:50}} >red<Text>
實(shí)際開發(fā)推薦用法:在StyleSheet.create中幾種定義樣式,如下

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

class LotsOfStyles extends Component {
  render() {
    return (
      <View>
        <Text style={styles.red}>just red</Text>
        <Text style={styles.bigblue}>just bigblue</Text>
        <Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
        <Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  bigblue: {
    color: 'blue',
    fontWeight: 'bold',
    fontSize: 30,
  },
  red: {
    color: 'red',
  },
});

AppRegistry.registerComponent('LotsOfStyles', () => LotsOfStyles);

寬度和高度

指定寬高

最簡單的方式:直接指定height和width,在react native中像素都是luo'ji邏輯像素?zé)o單位,例子如下:

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

class FixedDimensionsBasics extends Component {
  render() {
    return (
      <View>
        <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
        <View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
        <View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
};
// 注冊應(yīng)用(registerComponent)后才能正確渲染
// 注意:只把應(yīng)用作為一個整體注冊一次,而不是每個組件/模塊都注冊
AppRegistry.registerComponent('AwesomeProject', () => FixedDimensionsBasics);

彈性(Flex)寬高

在style中使用flex可以動態(tài)的擴(kuò)張和收縮。在一個父組件只有一個子組件的情況下給子組件指定flex:1可以使得子組件撐滿父組件,但子組件有多個時子組件按照各自的權(quán)重分配空間

組件能夠撐滿剩余空間的前提是父容器的大小不為0,父容器沒有指定width和height,也沒有指定flex,那么父容器的尺寸就為0。
下面是一個flex使用示例:

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

class FlexDimensionsBasics extends Component {
  render() {
    return (
      // 試試去掉父View中的`flex: 1`。
      // 則父View不再具有尺寸,因此子組件也無法再撐開。
      // 然后再用`height: 300`來代替父View的`flex: 1`試試看?
      <View style={{flex: 1}}>
        <View style={{flex: 1, backgroundColor: 'powderblue'}} />
        <View style={{flex: 2, backgroundColor: 'skyblue'}} />
        <View style={{flex: 3, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
};

AppRegistry.registerComponent('AwesomeProject', () => FlexDimensionsBasics);

效果如下:

效果示例

FlexBox布局

一般來說我們使用flexDirection、alignItemsjustifyContent來實(shí)現(xiàn)大多數(shù)的布局

RN的flexbox布局和web中的css布局基本類似,只存在少許的差異。首先默認(rèn)值不同:flexDirection的默認(rèn)值是cloumn而不是row,alignItem默認(rèn)值是stretch而不是flex-start,flex只能指定一個值

FlexDirection

style中指定flexDirection可以指定主軸,他有兩個取值,默認(rèn)值column以及另一個值row,下面是一個例子:

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

class FlexDirectionBasics extends Component {
  render() {
    return (
      // 嘗試把`flexDirection`改為`column`看看
      <View style={{flex: 1, flexDirection: 'row'}}>
        <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
};

AppRegistry.registerComponent('AwesomeProject', () => FlexDirectionBasics);

效果主軸為水平:

主軸為水平軸
主軸為垂直軸

JustifyContent

在style中指定justifyContent可以指定子元素沿著主軸的排列方式,選項(xiàng)有flex-start,center,flex-end,space-around,space-between。
代碼示例:

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

class JustifyContentBasics extends Component {
  render() {
    return (
      // 嘗試把`justifyContent`改為`center`看看
      // 嘗試把`flexDirection`改為`cloumn`看看
      <View style={{
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-between',
      }}>
        <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
};

AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);

效果圖:
flex-start:


flex-start

center:

center

flex-end:

flex-end

space-around:

space-around

space-between:

space-between

alignItems

在組件style中指定alignItems可以決定子元素沿著次軸的排列方式。他有四個選項(xiàng):?flex-startcenter、flex-endstretch。

想要stretch生效的話子元素在次軸上不能有固定的尺寸

示例代碼:

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

class AlignItemsBasics extends Component {
  render() {
    return (
      // 嘗試把`alignItems`改為`flex-start`看看
      // 嘗試把`justifyContent`改為`flex-end`看看
      // 嘗試把`flexDirection`改為`row`看看
      <View style={{
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
      }}>
        <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
      </View>
    );
  }
};

AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);

效果圖:
flex-start:

flex-start

center:

center

flex-end:

flex-end

stretch:此時我們是將主軸設(shè)為row所以垂直方向不能設(shè)置也就是不能設(shè)置高度。

stretch

文本輸入

TextInput是一個文本輸入的基礎(chǔ)組件。有一個名為onChangeeText屬性,通過這個屬性可以獲取組件中的文本,下面是代碼例子:

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

class PizzaTranslator extends Component {
  constructor(props) {
    super(props);
    this.state = {text: ''};
  }

  render() {
    return (
      <View style={{padding: 10}}>
        <TextInput
          style={{height: 40}}
          placeholder="Type here to translate!"
          onChangeText={(text) => this.setState({text})}
        />
        <Text style={{padding: 10, fontSize: 42}}>
          {this.state.text.split(' ').map((word) => word && '??').join(' ')}
        </Text>
      </View>
    );
  }
}
// 注冊應(yīng)用(registerComponent)后才能正確渲染
// 注意:只把應(yīng)用作為一個整體注冊一次,而不是每個組件/模塊都注冊
AppRegistry.registerComponent('PizzaTranslator', () => PizzaTranslator);

ScroView的使用

ScrollView是一個通用的容器,可以在其中放入scrollView,下面是一個ScrollView

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

class IScrolledDownAndWhatHappenedNextShockedMe extends Component {
  render() {
      return(
        <ScrollView>
          <Text style={{fontSize:96}}>Scroll me plz</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:96}}>If you like</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:96}}>Scrolling down</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:96}}>What's the best</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:96}}>Framework around?</Text>
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Image source={require('./img/favicon.png')} />
          <Text style={{fontSize:80}}>React Native</Text>
        </ScrollView>
    );
  }
}

// 注冊應(yīng)用(registerComponent)后才能正確渲染
// 注意:只把應(yīng)用作為一個整體注冊一次,而不是每個組件/模塊都注冊
AppRegistry.registerComponent(
  'IScrolledDownAndWhatHappenedNextShockedMe',
  () => IScrolledDownAndWhatHappenedNextShockedMe);

ScrollView是用來顯示數(shù)量不多的元素,它不同于ListView,它會渲染所有的子組件,而不是像ListView一樣只渲染可見的部分
效果圖如下:

ScrollView

這里講一下ScrollView的兩個屬性,第一個horizontal,這是一個bool類型的屬性,當(dāng)它為true時候他就是一個左右滑動的ScrollView,默認(rèn)值為false垂直滑動 ,另一個屬性是automaticallyAdjustContentInsets這個屬性當(dāng)ScrollView作為TabBar或者Navigator后面的時候,ios是否自動調(diào)整內(nèi)容的范圍(如果ScrollView或者ListView出現(xiàn)莫名其妙的空白那就將這個屬性設(shè)置為false),還有一個要點(diǎn)就是ScrollView一定要指定高度(垂直的時候)或?qū)挾龋ㄋ降臅r候)

ListView

ListView組件用于顯示垂直滾動列表,它只會渲染其中的可見部分適用于長列表,ListView列表必須有兩個屬性,dataSource和renderRow。dataSource是列表的數(shù)據(jù)源,它是一個ListView.DataSource類型對象,redenderRow從dataSource中取數(shù)據(jù)并渲染。

rowhasChange是ListView的dataSource中的必備屬性

下面是一個示例:

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

class ListViewBasics extends Component {
  // 初始化模擬數(shù)據(jù)
  constructor(props) {
    super(props);
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds.cloneWithRows([
        'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
      ])
    };
  }
  render() {
    return (
      <View style={{paddingTop: 22}}>
        <ListView
          dataSource={this.state.dataSource}
          renderRow={(rowData) => <Text>{rowData}</Text>}
        />
      </View>
    );
  }
}

// 注冊應(yīng)用(registerComponent)后才能正確渲染
// 注意:只把應(yīng)用作為一個整體注冊一次,而不是每個組件/模塊都注冊
AppRegistry.registerComponent('ListViewBasics', () => ListViewBasics);

例子示例如下:

ListView

網(wǎng)絡(luò)

Fetch

React Native提供了和web標(biāo)準(zhǔn)一致的Fetch API

發(fā)起網(wǎng)絡(luò)請求

從任意地址獲取數(shù)據(jù)內(nèi)容,只需要簡單件網(wǎng)址傳給fetch方法即可
fetch('https://www.baidu.com')
fetch有許多可以定制的參數(shù),示例如下:

fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    firstParam: 'yourValue',
    secondParam: 'yourOtherValue',
  })
})

這段代碼定制了提交方式 請求頭和請求體

處理服務(wù)器的響應(yīng)數(shù)據(jù)

代碼示例:

fetch('http://facebook.github.io/react-native/movies.json')
      .then((response) => response.json())
      .then((responseJson) => {
        return responseJson.movies;
      })
      .catch((error) => {
        console.error(error);
      });

fetch語句返回的是一個Promise對象,可以通過then進(jìn)行異步操作promise.then().then(),then中跟的參數(shù)是前面的的返回值。

Navigator

導(dǎo)航器的使用示例:

<Navigator
    initialRoute={{ name: 'first', component: LatestRelease }}
    configureScene={
        (route) => {
            return Navigator.SceneConfigs.VerticalUpSwipeJump;
        }
    }
    renderScene={
        (route, navigator) => {
            let Component = route.component;
            return <Component {...route.params} navigator={navigator} />
        }
    }
    >

</Navigator>
export default class LatestRelease extends Component {

    _showDetail() {
        const {navigator} = this.props;
        if (navigator) {
            navigator.push({
                name: 'Detail',
                component: Detail,
            })
        }
    }


    render() {
        const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        return (
            <View style={{flex: 1}}>
                <View alignItems='center'>
                    <View style={{backgroundColor: '#F8F8FF'}}><Text>最新發(fā)布</Text></View>
                    <TextInput style={{height: 30, margin: 5, padding: 2, borderColor: 'gray', borderWidth: 1}}
                               placeholder='搜索'/>
                </View>

                <View style={{
                    height: 30,
                    margin: 5,
                    backgroundColor: 'deepskyblue',
                    alignItems: 'center',
                    flexDirection: 'row'
                }}>
                    <View style={{flex: 1}}>
                        <Text style={{color: 'white', paddingLeft: 5}}>指標(biāo)</Text>
                    </View>
                    <View style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-end'}}>
                        <Text style={{color: 'white'}}>同比(%) </Text>
                    </View>
                </View>
                <ListView
                    automaticallyAdjustContentInsets={false}
                    style={{flex: 7, marginLeft: 5, marginRight: 5}}
                    dataSource={ds.cloneWithRows(['國內(nèi)生產(chǎn)總值', '水泥', '固定資產(chǎn)投資(不含農(nóng)戶)', '民間固定資產(chǎn)投資', '房地產(chǎn)開發(fā)投資', '社會消費(fèi)品零售總額']) }
                    renderRow={(rowData) =>
                        <TouchableHighlight onPress={this._showDetail.bind(this) } style={{
                            height: 40,
                            marginBottom: 5,
                            borderBottomWidth: 1,
                            borderBottomColor: 'lightgray'
                        }} flexDirection='row' alignItems='center'>
                            <View style={{flex: 1}} flexDirection='row' alignItems='center'>
                                <View style={{flex: 9}}>
                                    <Text style={{paddingTop: 5, fontSize: 15}}>{rowData}</Text>
                                    <Text style={{}}>2016Q1-2</Text>
                                </View>
                                <View style={{flex: 1}}>
                                    <Text style={{fontSize: 18, color: 'red'}}>+6.7</Text>
                                </View>
                            </View>
                        </TouchableHighlight>}
                >
                </ListView>
                <Button style={{backgroundColor: 'red'}} textStyle={{fontSize: 18}}
                        children={require('./Icon/add_zb_icon1.png')}
                >
                    Hello!word

                </Button>

                <ButtonComponent
                    text="添加指標(biāo)"
                    textStyle={{letterSpacing: 0,
                        fontSize: 15,
                        color: 'black',}}
                    image={require('./Icon/add_zb_icon1.png')}
                    shape='rectangle'
                    height={28}
                    width={100}
                    type="primary"
                    style={{margin:8}}
                    backgroundColors={['white', 'white']}
                />
            </View>
        );
    }
}

initialRoute 和renderScene是導(dǎo)航器組件中必須聲明的屬性,initialRoute指定導(dǎo)航器的初始渲染組件,renderScene是渲染場景時的行為

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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