觀看筆記:零基礎 React Native 實戰開發視頻 50講html
本篇效果:RN入門,總體認識react
一個簡單的例子android
/** * Sample React Native App * https://github.com/facebook/react-native */ 'use strict'; import React, { AppRegistry, Component, StyleSheet, Text, View } from 'react-native'; # 引入組件
class DongFang extends Component { render() { return ( <View style={styles.container}> <Text style={styles.welcome}> Welcome to React Native!東方耀的第5課 </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> ); } }
# 樣式表 系統api 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('DongFang', () => DongFang);
UI利器:彈性盒子佈局,主流瀏覽器都支持。git
講義:http://www.cnblogs.com/dfy888/p/5374329.htmlgithub
參考:阮一峯: Flex 佈局教程:語法篇chrome
參考:阮一峯: Flex 佈局教程:實例篇json
jsx是個語法糖;react-native
(1) 轉換 解析器 html --> js,而後在瀏覽器運行。 api
(2) 執行js表達式。html with js --> js數組
(3) 執行js表達式。屬性 --> js
(4) 執行js表達式。延展屬性 --> js,使用ES6語法。
(5) 以字符串的形式完整顯示HTML,藉助_html屬性
(6) 樣式style的使用,好比顏色,字體大小。
(7) 事件綁定 - button
React.createClass: 建立組件類的方法。
React.render: 將制定組件渲染到制定的DOM節點。【會被ReactDOM.render替代】
Ref: React Native Component Lifecycle【簡潔,清晰】
如圖,能夠把組件生命週期大體分爲三個階段:
生命週期 | 調用次數 | 可否使用 setSate() |
---|---|---|
建立階段,處理props的默認值 | ||
getDefaultProps | 1(全局調用一次) | 否 |
實例化階段,React.render(<HelloMessage 啓動以後 State:ReactJS內部監聽state屬性的變化,一旦發生變化,主動觸發組件的render方法更新虛擬DOM結構, which is 真實的DOM結構映射成一個json數據結構。 |
||
getInitialState | 1 | 否 |
componentWillMount | 1 | 是 |
render | >=1 | 否 |
componentDidMount | 1 | 是 |
更新階段,根據用戶操做行爲進行相應的頁面結構的調整。 | ||
componentWillReceiveProps | >=0 | 是 |
shouldComponentUpdate | >=0 | 否 |
componentWillUpdate | >=0 | 否 |
componentDidUpdate | >=0 | 否 |
銷燬階段,取消事件綁定、移除虛擬DOM等。 | ||
componentWillUnmount | 1 | 否 |
父子組件之間的通訊方式?
Ref: http://blog.csdn.net/p106786860/article/details/52408875 【代碼實例】
var Parent=React.craeteClass({
click:function() {
this.refs.child.getDOMNode().stype.color="red";
},
render:function() {
return (
<div onClick={this.click} >Parent is :
<Child name={this.props.name} ref="child"></Child>
</div> ); #子組件 調用 父組件
}
});
var Child=React.craeteClass({
render:function() {
return <span> {this.props.name} </span>
}
});
ReactDOM.render(<Parent name="React語法基礎" />, document.getElementById('example'));
Ref: react native 之子組件和父組件之間的通訊
*** 父組件 --> 子組件 ***
/** * Sample React Native App * https://github.com/facebook/react-native * 父組件傳遞給子組件 * 父組件把值或者navigator傳給子組件,而後在子組件裏面實現push和顯示 */ import React, { Component } from 'react'; import ChildOne from './ChildOne' import { AppRegistry, StyleSheet, Text, View } from 'react-native'; export default class HomeOne extends Component { render() { return (
// 相似:調用函數,將參數傳入子函數,將參數看做一種通訊方式 <ChildOne navigatorPush = {this.props.navigator} passValue = '我是一個父組件傳給子組件的值'/> ); } } 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, }, });
子組件,childOne的代碼:經過 this.props.屬性名 使用傳過來的值。
/** * Sample React Native App * https://github.com/facebook/react-native * 父組件傳遞給子組件 */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, navigator, } from 'react-native';
import OneDetails from './OneDetails'
export default class ChildOne extends Component { render() { return ( <View style={styles.container}> <Text style={styles.welcome} onPress={()=>this.pushOneDetails()}> 我是子組件ONE </Text> <Text> {this.props.passValue} # 直接獲取 </Text> </View> ); } pushOneDetails = ()=>{ this.props.navigatorPush.push({ component: OneDetails }) } } 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, }, });
*** 父組件 --> 子組件 ***
子組件經過定義一個屬性直接把事件傳遞給主組件。
/** * Sample React Native App * https://github.com/facebook/react-native * 子組件傳遞給父組件 */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View } from 'react-native'; export default class ChildTwo extends Component { static defaultProps = { two: '我是子組件傳給主組件的值' }; render() { return ( <Text style={styles.welcome} onPress={()=>this.passMenthod()}> 我是子組件TWO </Text> ); } passMenthod = () =>{ this.props.pushDetails() } } 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, }, });
父組件這邊直接經過子組件的屬性來接受事件,從而在主組件這邊push和pop。
/** * Sample React Native App * https://github.com/facebook/react-native * 子組件傳遞給父組件 * 子組件把事件或值傳遞給父組件,而後在父組件push和顯示 */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View } from 'react-native'; import ChildTwo from './ChildTwo' import TwoDetails from './TwoDetails'
export default class HomeTwo extends Component { // 構造 constructor(props) { super(props); // 初始狀態 this.state = { value:'' }; } render() { return ( <View style={styles.container}> <ChildTwo pushDetails = {()=>this.pushDetails()} /> <Text> {ChildTwo.defaultProps.two} </Text> </View> ); } pushDetails = ()=>{ this.props.navigator.push({ component:TwoDetails }) } } 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, }, });
整體感受,須要一個系統的文章來學習,以上關於通訊這塊,仍是很零碎,須要看書上的相關章節來系統地增強認識。
繼續細細分析【props】和【state】in: [RN] Try a little bit of React Native
咱們使用兩種數據來控制一個組件:props和state。
關於屬性:props
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { Platform, StyleSheet, Text, View, Image } from 'react-native'; export default class App extends Component { render() {
let pic = { uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg' }; // 以下:pic 被一個 控件所引用 return ( <Image source={pic} style={{width: 193, height: 110}}/> );
} }<Image/>
{pic} 括號把JSX語句嵌入其中,括號裏多是表達式也能夠是js變量,因此,這一切 均可以是 動態的。
例以下面這代碼:
import React, { Component } from 'react'; import { AppRegistry, Text, View } from 'react-native';
// 建立了一個 Greeting 對象 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);
關於狀態:state
1 .props是在父組件中指定,一經指定,在被指定的生命週期中則再也不改變
2 .對於須要改變的數據,咱們須要使用state
3 .須要在constructor中初始化state,而後在須要修改時調用setState方法。
/** * Sample React Native App * https://github.com/facebook/react-native * @flow 此代碼可直接運行 */ import React, { Component } from 'react'; import { Platform, StyleSheet, Text, View } from 'react-native'; class Blink extends Component {
constructor(props) { super(props); this.state = { showText: true };
// 調用計時器方法 // 每1000毫秒對showText狀態作一次取反操做 setInterval(() => { this.setState({ showText: !this.state.showText }); }, 1000); }
render() { // 根據當前showText的值決定是否顯示text內容 let display = this.state.showText ? this.props.text : ' '; return ( <Text>{display}</Text> ); }
}
// main export default class App extends Component<Props> { 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> ); } }
關於樣式:style
一個View能夠有多個樣式屬性,他們以數組形勢共存,
固然若是多個樣式出現重複,排在右邊的會覆蓋以前的,具體狀況咱們看一例子:
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);
(1). 啓動js服務器。
(2). 肯定手機鏈接可靠。
(3). 加載代碼。
(4). 設置爲與本地同一網段:Dev Settings。
(5). 點擊Debug server host & port for device,設置ip地址。
Reload JS:手動刷新
Debug JS:遠端調試工具,須要chrome。
Enable Live Reload:自動刷新
檢查元素
Enable Perf Monitor
Dev Settings
原理:包服務器,手機端調試依賴這個bundle,也涉及到熱更新。
F12進入開發者模式,而後經過瀏覽器調試,這是Google的牛逼之處。【Debug JS】
固然,Facebook的RN也提供了在線手機上的簡單版本的frond-end調試。【檢查元素】
發佈六步驟
(1). 建立密鑰
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
生成了用於應用發佈的祕鑰: my-release-key.keystore
(2). bundle文件
在工程目錄下將index.android.bundle下載並保存到assets資源文件中。
首先,建立文件夾:./android/app/src/main/assets;而後,執行命令:
curl -k "http://localhost:8081/index.android.bundle" > android/app/src/main/assets/index.android.bundle
(3). 配置gradle中的簽名
(4). 在build.gradle中設置密鑰的屬性
接下來,使簽名生效:添加一行,以下:
(5). 爲減少發佈包的大小,修改以下屬性爲true
若是是涉及到第三方庫,會修改app/proguard-rules.pro。在此,先保持默認配置。
(6). gradle打包併發布
在android目錄下執行,便自動編譯打包。
gradle assembleRelease
執行成功後在下面的目錄中會生成對應的release的兩個版本。
RN主目錄:
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000 [注:在產生的時候須要提供密鑰和存儲密碼,後續會用到] mv my-release-key.keystore android/app/
Step 2:
android/gradle.properties文件: MYAPP_RELEASE_STORE_FILE = my-release-key.keystore // 簽名文件
MYAPP_RELEASE_KEY_ALIAS = my-key-alias
MYAPP_RELEASE_STORE_PASSWORD = xx
MYAPP_RELEASE_KEY_PASSWORD = xx
[注意替換xx爲你本身設置的密鑰和存儲密碼]
Step 3:
android/app/build.gradle文件: ... android { ... defaultConfig { ... }
signingConfigs { release { storeFile file(MYAPP_RELEASE_STORE_FILE) storePassword MYAPP_RELEASE_STORE_PASSWORD keyAlias MYAPP_RELEASE_KEY_ALIAS keyPassword MYAPP_RELEASE_KEY_PASSWORD } }
buildTypes { release { ... signingConfig signingConfigs.release } } }
cd android/
./gradlew assembleRelease