[React Native Android安利系列]創建簡單RN應用(以js角度來看RN)

書接上回,我們已經掌握了如何使用android studio與reactnative搭建一個react的基礎環境,并使用其成功的制作出了一個hello world,接下來,我們要探索一下如何利用react-native制作出比HelloWorld復雜一點的界面(雖然是個界面都比helloWorld復雜),順便一起審視一些ReactNativeAndroid工程的目錄結構。

1. 目錄結構

首先我們來回顧一下,我們的helloReact工程的目錄結構。

打開CMD,或者終端,我們可以看到helloReact工程下,有三個目錄,和三個文件,如圖1.1所示

圖1.1

1.1 android目錄

這個就是咱們的安卓工程了。里面存放著生成的android應用代碼。

1.2 IOS目錄

這個是IOS開發的目錄,之后的react-native ios篇,我們再詳細聊一下。

1.3 index.android.js

這個是安卓版本的js入口。

1.4 index.ios.js

這個是ios版本的js入口。

1.5 package.json

這個是本項目,這里記載著項目的基本數據和依賴項。

1.6 node_modules

這個是項目依賴的npm庫的代碼。其中當然也包括ReactNative代碼的源碼,在之后的章節里面,我們將會一起來讀一下ReactNative的源代碼。

2. 查看項目js

我們詳細來看一下index.android.js,這里用的是es6的語法,不過對于一般做過前端的人來說,是可以看懂了,做java的應該也大致能看懂這里寫的是什么。

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

class hellowReact extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.android.js
        </Text>
        <Text style={styles.instructions}>
          Shake or press menu button for dev menu
        </Text>
      </View>
    );  
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },  
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

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

位于上方的1~8行是對于react-native依賴的導入

接下來9~25行,定義了一個react的類,一個簡單的類,只需要擁有render方法即可渲染,在render方法中,我們返回了需要渲染的組件的組合。

請注意,在render中返回的并不是字符串,而是JSX語法的組件組合。這些組件渲染至APP中。并且在JSX中,我們直接輸出了變量{styles.xxx},在jsx中,我們的js變量如需輸出,則需要放置在界符中{}

再次注意,在這里,我們使用js去調用了react-native提供的原生組件,就像網頁上的HTML標簽一樣,這更接近web編程。接下來,我們還會分享更多組件的用法。

27~44行,則大致向我們展示了react-native的樣式寫法。以一種js的方式去定義樣式表,但是屬性和取值,使用的也的確很像我們親切的css

最后將45~46行,將寫好的組建,注冊至react-native。

3. 動手改寫,寫一個自定義的屬性

接下來,我們要自定義一個變量,變量里面填充好數據,待點擊后,讓View發生變化。

首先我們給hellowReact類,添加構造方法:

class hellowReact extends Component {
  constructor(props) {
    super(props);
    // 定義了初始的狀態
    this.state = {
        word: 'hello'
    };
  }

  render() {
    // 在JSX中,直接使用state中定義的word->this.state.word,并進行輸出
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
            {this.state.word}
        </Text>
      </View>
    );
  }
}

構造方法中,指定了helloReact的state屬性,其中有一個word屬性。在這里,我們也把render方法改變一下。直接將helloReact組建的state中的word屬性,渲染至界面上,搖一搖手中打開的helloReact的APP,點擊reloadjs,重新加載我們更改過的js(結果如圖3.1所示)

圖3.1

此時,我們看到界面上渲染了,我們的word,"hello"。

接下來,我們需要再次對我們的APP進行一些改造

class hellowReact extends Component {
  constructor(props) {
    super(props);
    this.state = {
        word: 'hello'
    };
  }
  // 更改state中word的函數
  changeWord() {
    // 更改狀態,將word變量,更改為'world'
    this.setState({
      word: 'world'
    });
  }

  render() {
    // 點擊時觸發changeWord函數,更改狀態
    return (
      <View style={styles.container} onTouchEnd={this.changeWord.bind(this)}>
        <Text style={styles.welcome}>
            {this.state.word}
        </Text>
      </View>
    );
  }
}

我們在View發生touchEnd的時候,調用自定義函數,changeWord。該方法將調用方法setState,將state中的word進行更改。

緊接著,我們再次在APP上reloadjs。渲染的還是之前的hello,我們點擊界面,則界面渲染為"world"(如圖3.2所示)

圖3.2

4. 回顧一下,我們都干了什么

通過上述的實踐,我們發現,其實react將我們的界面組件,看做一個狀態機,在定義的render方法中,我們將"組件"與"狀態"的糅雜--JSX,告知react,react在用戶觸發了狀態變化時,幫我們重新進行了渲染。這個行為,在組件中的體現,就是setState。于是我們驚喜的發現,我們只要更改狀態(setState)就好了。至于渲染,則不用操心,我們調用了setState,界面自動就被重新渲染了。

而事件綁定,也像極了web編程中的DOM上綁定onclick事件的做法。在touchEnd的時候,會觸發我們預先設定好的回掉函數。

5. 創建一個react-native-android的簡單列表

接下來,我們要一起做一個列表項。首先,我們引入react-native提供的組建,ListView。

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

import的列表中,最后加入ListView。

然后,我們在constructor里面,加入一個狀態

constructor(props) {
    super(props);
    var list = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      list: list.cloneWithRows(['hello', 'react', 'this', 'is', 'my', 'listView'])
    };
  }

是一個符合ListView格式的數據源。接下來,我們在render中渲染這個ListView

render() {
    return (
      <View style={styles.container}>
        <ListView
          dataSource={this.state.list}
          renderRow={this.oneRow}
        />
      </View>
    );
  }

其中,renderRow屬性,指定的是,渲染ListView中每一項的方法。我們可以直接寫個比較簡單的text組件。

oneRow(oneItem) {
    return <Text>{oneItem}</Text>;
  }

我們看看整體的代碼

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

class hellowReact extends Component {
  constructor(props) {
    super(props);
    var list = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      list: list.cloneWithRows(['hello', 'react', 'this', 'is', 'my', 'listView'])
    };
  }
  oneRow(oneItem) {
    // 提供列表中,每一個item的渲染方式
    return <Text>{oneItem}</Text>;
  }
  render() {
    // 渲染中使用了列表
    return (
      <View style={styles.container}>
        <ListView
          dataSource={this.state.list}
          renderRow={this.oneRow}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});

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

保存后,我們reload一下新改好的js。結果如圖5.1所示

圖5.1

這里,我們學會了,如何使用js去調用react-native提供的原生組件。原生組件有很多,基本能覆蓋我們日常開發需要的基礎組件(如剛剛的ListView/View/Text等),但是還有很多我們個性化的需求,無法滿足的時候,我們又該怎么辦呢?這一系列會詳細講解React中js調用原生代碼的方法。

上述講解,可以在這里找到相關例子:

https://github.com/houyu01/re...

下節更精彩,我們將來一起看看android原生的小知識,加強我們開發react-native的底層了解。不要走開,請關注我.....

系列文章

[React Native Android安利系列]搭建React Native Android環境 
[React Native Android安利系列]創建簡單 RN 應用(以js角度來看RN)
[React Native Android安利系列]原生小知識(創建activity并跳轉)

 

來自:https://segmentfault.com/a/1190000006059149

 

 本文由用戶 tcwe2462 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!