中秋在家閒得無事,想着作點啥,後來想一想,爲啥不學學 react native。在學習 React Native 時, 須要對前端(HTML,CSS,JavaScript)知識有所瞭解。對於JS,能夠看看阮一峯老師的《ECMAScript 6 入門》這篇文章。裏面涉及不少 ES6 的新特性。我以前也是看了阮老師的文章作了一些學習筆記 ES6 學習筆記。 javascript
環境搭建中文教程,點擊跳轉RN中文社區 :http://reactnative.cn/docs/0.40/getting-started.html#contenthtml
社區內容講得很詳細,你們跟着操做一步一步來便可,遇到問題,直接百度。也能夠看看這篇文章:React Native 填坑指南 會教你如何把坑填平。前端
先來看看一個實例,這個地址源碼地址:示例教程:電影列表。之因此選擇這個例子,是由於它包含了幾乎全部的 react native入門基礎知識。java
import React, { Component } from "react"; import { Image, FlatList, StyleSheet, Text, View } from "react-native"; var REQUEST_URL = "https://raw.githubusercontent.com/facebook/react-native/0.51-stable/docs/MoviesExample.json"; export default class SampleAppMovies extends Component { constructor(props) { super(props); this.state = { data: [], loaded: false }; // 在ES6中,若是在自定義的函數裏使用了this關鍵字,則須要對其進行「綁定」操做,不然this的指向會變爲空 // 像下面這行代碼同樣,在constructor中使用bind是其中一種作法(還有一些其餘作法,如使用箭頭函數等) this.fetchData = this.fetchData.bind(this); } componentDidMount() { this.fetchData(); } fetchData() { fetch(REQUEST_URL) .then(response => response.json()) .then(responseData => { // 注意,這裏使用了this關鍵字,爲了保證this在調用時仍然指向當前組件,咱們須要對其進行「綁定」操做 this.setState({ data: this.state.data.concat(responseData.movies), loaded: true }); }); } render() { if (!this.state.loaded) { return this.renderLoadingView(); } return ( <FlatList data={this.state.data} renderItem={this.renderMovie} style={styles.list} /> ); } renderLoadingView() { return ( <View style={styles.container}> <Text>Loading movies...</Text> </View> ); } renderMovie({ item }) { // { item }是一種「解構」寫法,請閱讀ES2015語法的相關文檔 // item也是FlatList中固定的參數名,請閱讀FlatList的相關文檔 return ( <View style={styles.container}> <Image source={{ uri: item.posters.thumbnail }} style={styles.thumbnail} /> <View style={styles.rightContainer}> <Text style={styles.title}>{item.title}</Text> <Text style={styles.year}>{item.year}</Text> </View> </View> ); } } var styles = StyleSheet.create({ container: { flex: 1, flexDirection: "row", justifyContent: "center", alignItems: "center", backgroundColor: "#F5FCFF" }, rightContainer: { flex: 1 }, title: { fontSize: 20, marginBottom: 8, textAlign: "center" }, year: { textAlign: "center" }, thumbnail: { width: 53, height: 81 }, list: { paddingTop: 20, backgroundColor: "#F5FCFF" } });
這個例子從電影數據庫中取得最近正在上映的 25 部電影,並在一個 FlatList
中展現出來。react
import React,{Component} from 'react'; // 導入‘react’文件裏export的一個默認的組件,將其命名爲React以及Component這個非默認組件
還有其餘一些 import 的用法,具體含義以下:ios
import {a} from 'XXX' 導入 XXX 文件中的 a 組件git
import {a as b} from 'XXX' 導入 XXX 文件中的a組件,並將其重命名爲 bes6
import * as a from 'XXX' 導入 XXX 文件中的全部組件,並將其命名爲 a,調用具體組件的方式爲 a.b、a.c。。。但不包含默認組件github
在組件前面,定一個變量 REQUEST_URL 用於保存請求網址,。web
模塊的功能有兩個關鍵字: export 和 import。export 用於用戶自定義模塊。import用於輸入其餘模塊的功能,同時建立命名空間(namespace),防止函數名衝突。
ES6容許將獨立的JS文件做爲模塊,也就是說,容許一個 JavaScript 腳本文件調用另外一個腳本文件。最簡單的模塊就是一個 JS 文件,裏面使用 export 關鍵字輸出變量。
//profile.js export var firstName = "Pandora"; export var lastName = "G.Dragon"; export var year = 1973; //export還有下面這種寫法,二者是等價的 var firstName = "Pandora"; var lastName = "G.Dragon"; var year = 1973; export({firstName, lastName, year});
使用 export 定義模塊以後,其餘 JS 文件就能夠經過 import 關鍵字加載這個模塊(文件)了。加載方式以下:
import {firstName, lastName, year} from './profile'; function setHeader(element) { element.textContent = firstName + '' + lastName; }
上面的代碼片斷中,使用了 import 關鍵字接受一個對象——用「{ }」表示。裏面指定了要從其餘模塊中導入的變量。大括號裏面的變量名必須與被導入模塊對外接口的名稱相同。
ES6 提供了更接近傳統語言的寫法,引入了 Class(類)這個概念,做爲對象的模板。經過class
關鍵字,能夠定義類。基本上,ES6 的 class 能夠看做只是一個語法糖,它的絕大部分功能,ES5 均可以作到,新的class
寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。上面的代碼用 ES6 的「類」改寫,就是下面這樣。
//定義類 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
上面代碼定義了一個「類」,能夠看到裏面有一個 constructor
方法,這就是構造方法,而 this
關鍵字則表明實例對象。也就是說,ES5 的構造函數 Point
,對應 ES6 的 Point
類的構造方法。
Point 類除了構造方法,還定義了一個 toString
方法。注意,定義「類」的方法的時候,前面不須要加上 function
這個關鍵字,直接把函數定義放進去了就能夠了。另外,方法之間不須要逗號分隔,加了會報錯。
Class 之間能夠經過 extends
關鍵字實現繼承,這比 ES5 的經過修改原型鏈實現繼承,要清晰和方便不少。
class ColorPoint extends Point {}
上面代碼定義了一個 ColorPoint
類,該類經過 extends
關鍵字,繼承了 Point
類的全部屬性和方法。可是因爲沒有部署任何代碼,因此這兩個類徹底同樣,等於複製了一個 Point
類。下面,咱們在 ColorPoint
內部加上代碼。
class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // 調用父類的constructor(x, y) this.color = color; } toString() { return this.color + ' ' + super.toString(); // 調用父類的toString() } }
上面代碼中,constructor
方法和 toString
方法之中,都出現了super
關鍵字,它在這裏表示父類的構造函數,用來新建父類的 this
對象。
子類必須在 constructor
方法中調用 super
方法,不然新建實例時會報錯。這是由於子類沒有本身的 this
對象,而是繼承父類的 this
對象,而後對其進行加工。若是不調用super
方法,子類就得不到 this
對象。
大多數組件在建立時就可使用各類參數來進行定製。用於定製的這些參數就稱爲props
(屬性)。
以常見的基礎組件 Image
爲例,在建立一個圖片時,能夠傳入一個名爲 source
的 prop 來指定要顯示的圖片的地址,以及使用名爲 style
的 prop 來控制其尺寸。
import React, { Component } from 'react'; import { Image } from 'react-native'; export default 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}} /> ); } }
props 是在父組件中指定,並且一經指定,在被指定的組件的生命週期中則再也不改變。 對於須要改變的數據,咱們須要使用 state。
大多數組件在建立時就可使用各類參數來進行定製。用於定製的這些參數就稱爲 props
(屬性)。
通常來講,你須要在 constructor 中初始化 state
(譯註:這是 ES6 的寫法,早期的不少 ES5 的例子使用的是 getInitialState 方法來初始化 state,這一作法會逐漸被淘汰),而後在須要修改時調用 setState
方法。
提示一些初學者應該牢記的要點:
一切界面變化都是狀態 state 變化
state
的修改必須經過 setState()
方法
this.state.likes = 100; // 這樣的直接賦值修改無效!
setState 是一個 merge 合併操做,只修改指定屬性,不影響其餘屬性
setState 是異步
操做,修改不會立刻生效
組件的生命週期方法對應着組件的不一樣生命階段,一般咱們分爲三個階段:組件初始化及掛載階段、組件運行期階段及組件卸載階段。
1、這是組件類的構造函數,一般在此初始化 state 數據模型。
constructor(props) { super(props); this.state = { //key : value }; }
2、表示組件將要加載到虛擬 DOM,在 render 方法以前執行,整個生命週期只執行一次。
componentWillMount() {
}
3、表示組件已經加載到虛擬 DOM,在 render 方法以後執行,整個生命週期只執行一次。一般在該方法中完成異步網絡請求或者集成其餘 JavaScript庫。
componentDidMount() {
}
1、在組件接收到其父組件傳遞的 props
的時候執行,參數爲父組件傳遞的props
。在組件的整個生命週期能夠屢次執行。一般在此方法接收新的props
值,從新設置 state
。
componentWillReceiveProps(nextProps) { this.setState({ //key : value }); }
2、在 componentWillReceiveProps(nextProps)
執行以後馬上執行;或者在state
更改以後馬上執行。該方法包含兩個參數,分別是 props
和 state
。該方法在組件的整個生命週期能夠屢次執行。若是該方法返回 false
,則 componentWillUpdate(nextProps, nextState)
及其以後執行的方法都不會執行,組件則不會進行從新渲染。
shouldComponentUpdate(nextProps, nextState) { return true; }
2、在 shouldComponentUpdate(nextProps, nextState)
函數執行完畢以後馬上調用,該方法包含兩個參數,分別是 props
和 state
。render()
函數執行以前調用。該方法在組件的整個生命週期能夠屢次執行。
componentWillUpdate(nextProps, nextState) {
}
3、在 render()
方法執行以後馬上調用。該方法包含兩個參數,分別是 props
和 state
。該方法在組件的整個生命週期能夠屢次執行。
componentDidUpdate(preProps, preState) {
}
4、render
方法用於渲染組件。在初始化階段和運行期階段都會執行。
render() { return( <View/> ); }
1、在組件由虛擬 DOM 卸載的時候調用。
componentWillUnmount() {
}
fetch,說白了,就是 XMLHttpRequest 的一種替代方案。若是有人問你,除了 Ajax 獲取後臺數據以外,還有沒有其餘的替代方案?答案是還可使用一種更優的解決方案 fetch。
到如今爲止,fetch 的支持性還不是很好,可是在谷歌瀏覽器中已經支持了fetch。fetch 掛在在 BOM 中,能夠直接在谷歌瀏覽器中使用。
查看 fetch 的支持狀況:fetch的支持狀況
fetch 方法會返回一個 Promise,這種模式能夠簡化異步風格的代碼。若是你想了解 promise 的含義,能夠參考文章 :手把手教你實現一個完整的 Promise 。帶你瞭解 promise 的本質內核。
下面咱們來寫第一個 fetch 獲取後端數據的例子:
// 經過fetch獲取百度的錯誤提示頁面 fetch('https://www.baidu.com/search/error.html') // 返回一個Promise對象 .then((res)=>{ return res.text() // res.text()是一個Promise對象 }) .then((res)=>{ console.log(res) // res是最終的結果 })
是否是很簡單?再來看看 get 和 post 方法的使用:
// 經過fetch獲取百度的錯誤提示頁面 fetch('https://www.baidu.com/search/error.html?a=1&b=2', { // 在URL中寫上傳遞的參數 method: 'GET' }) /* post 方法,把前面的 get 註釋便可 fetch('https://www.baidu.com/search/error.html', { method: 'POST', body: new URLSearchParams([["foo", 1],["bar", 2]]).toString() // 這裏是請求對象 }) */ .then((res)=>{ return res.text() }) .then((res)=>{ console.log(res) })
React Native 中已經內置了 XMLHttpRequest API (也就是俗稱的 ajax)。一些基於 XMLHttpRequest 封裝的第三方庫也可使用,例如 frisbee 或是 axios 等。但注意不能使用 jQuery,由於 jQuery 中還使用了不少瀏覽器中才有而 RN 中沒有的東西(因此也不是全部 web 中的 ajax 庫均可以直接使用)。
//todo 設置樣式一,直接在render中定義樣式 var mStyle = {color:'red',fontSize:34}; return<Text style={mStyle}> https://github.com/93Laer </Text> // or 相似於安卓中的匿名內部內 // return<Text style={{color:'red',fontSize:34}}> https://github.com/93Laer </Text>
// 建立樣式 const styles = StyleSheet.create({ bigblue:{ color:'blue', fontSize:34, fontWeight:'bold' }, red:{ color:'red', fontSize:14 } }); // 使用樣式 //todo 設置樣式二,經過StyleSheet建立樣式 return<Text style={styles.bigblue}> https ://github.com/93Laer </Text>
直接在組件中傳入多個 style 對象,最後顯示的效果就不展現了,在結尾直接給出結論
//這裏經過多種方式定義style,主要是告訴讀者定義style的多種方式 var mStyle = {color:'red',fontSize:34}; return<Text style={[mStyle,{color: 'blue',fontSize:20}]}> https ://github.com/93Laer </Text>
經過 StyleSheet 建立多個 style,並傳入
return<Text style={[styles.bigblue,styles.red]}> https ://github.com/93Laer </Text>
結論:當設置多個 style 時以最後一個爲準,可理解爲最後一個將以前的樣式覆蓋了。也可理解爲,style 從 styles 數組中依次拿出 style,並賦值給本身,因此最後一次賦值就會顯示效果
到此,關於 react native 入門的基礎知識就講解完畢了。