[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