接觸React Native有一段時間了,鑒于國內資料的缺乏,入門的時候相當痛苦,踩了不少坑,以下的筆記希望可以幫助和我一樣有投入RN熱情的同伴少走一些彎路,如有紕漏,歡迎大家交流指正
(除了百度、Google這兩位無名老師之外,感謝RN中文網和東方耀老師的視頻)
當前的編程環境:MacOS 10.11.4,Xcode 7.3.1,Android Studio 2.0,Sublime Text 2(插件配置以下有),RN的版本 0.26
個人推薦用Mac環境,環境配置簡單(具體請看RN中文網的配置,有些命令可能會出現權限問題,在命令前面加上sudo),可以做android和ios開發(需要提前安裝Xcode)
學習路線(配置完環境):html、css、js入門知識 ?---> React JS的入門及生命周期學習(掌握JSX語法) ---> RN組件學習(從View開始) ---> RN的彈性盒布局和API方法學習
環境部分
1.sublime安裝插件
(1)使用View > Show Console的方式打開命令行,然后用網絡找到的代碼安裝Package Control(具體方法百度),安裝之后重啟生效
(2)使用Sublime Text 2 > Preference > Package Control,選擇install Package,安裝以下插件:
Emmet(有自己的語法,快速寫CSS和HTML,文件名要html和css才可以生效)
HTML-CSS-JS Prettify ? ?格式化代碼
Spacegray ? ?主題,使整體更好看https://github.com/kkga/spacegray,安裝之后Sublime Text 2 > Preference > Settings-User,在里面引用相關的主題(可能要在之前的代碼后面加逗號),引用之后立刻生效,具體git上也有詳細說明
2.真機調試
相同的部分:USB連接手機,使電腦和手機在同個局域網(連同個wifi或者開電腦熱點)
ios:
(1)在命令行中找到項目文件夾,即ls命令可以看到index.ios.js的目錄,輸入react-native run-ios,啟動js服務器,看到 React packager ready. 并且沒有報錯實施下一步
(2)在項目文件夾中打開 ios -> [項目名稱].xcodeproj,找到AppDelegate.m中的jsCodeLocation變量,將里面localhost改為相對應的電腦 ip,然后運行真機,搖晃一下點擊Reload JS
android:
(1)配置好ANDROID_HOME環境(具體請百度),輸入adb devices可以看到連接的設備
(2)在命令行中找到項目文件夾,即ls命令可以看到index.android.js的目錄,輸入react-native run-android,啟動js服務器,看到 React packager ready. 并且沒有服務器啟動報錯實施下一步
(3)這時如果命令行有** BUILD FAILED **,看這一行上面的報錯,有可能是相對應的SDK版本或者ADT的版本不存在(比如默認的ADT 23.0.1版本沒下載到電腦),可以打開Android的SDK Manager安裝缺失的東西,然后再按照上一個步驟(若沒生效,可以重啟命令行試試)
(4)這時如果命令行有** BUILD SUCCEEDED **,搖晃手機或者點menu鍵可以出現一個菜單,點擊Dev Settings -> Debug server host & port for device,輸入電腦ip,確定,然后后退到主界面,搖晃手機或者點menu鍵,選擇Reload JS
注:可以在手機的瀏覽器中輸入 ?http://[電腦ip]:8081/index.ios.bundle?platform=ios&dev=true,觀察服務器的命令行是否有請求消息輸出,來判斷手機是否可以訪問到電腦的服務器
3.驗證JS服務器是否成功開啟
在命令行react-native run-ios(或者run-android)之后,有服務器的命令行彈出,這時在電腦瀏覽器中運行http://[電腦ip]:8081/index.ios.bundle?platform=ios&dev=true,命令行會有請求數據輸出,如 ?[14:16:46] request:/index.ios.bundle?plarform=ios&dev=true ? ? ? ?[14:16:46] request:/index.ios.bundle?plarform=ios&dev=true (19ms)
編程部分
1.React 生命周期
(1)初始化可以調用的函數:(組件還未渲染)
getDefaultProps????獲取實例的默認屬性,只調用一次,實例之間共享引用
getInitialState(在RN中constructor(props) 取代)初始化狀態,初始化各個實例特有的狀態
componentWillMount??組件即將被裝載,render之前最后一次修改狀態的機會
render??渲染虛擬的DOM節點,只能訪問 this.props 和 this.state ,只有一個頂層組件,不允許修改狀態和DOM輸出
componentDidMount??組件真正被裝載,成功render并渲染完成真實DOM之后觸發,可以修改DOM
(2)運行中可以調用的函數:
componentWillReceiveProps 組件在接收到屬性前觸發,父組件修改屬性觸發,可以修改新屬性、修改狀態
shouldComponentUpdate??當組件接收到新屬性和狀態的時候觸發,返回false會阻止render調用(小心使用)
componentWillUpdate??將要更新,不能修改屬性和狀態
render??同上
componentDidUpdate??會在組件更新完調用,可以修改DOM
(3)銷毀階段可以調用的函數:
componentWillUnmount??在組件真正銷毀之前調用
2.自定義組件要大寫
如var HelloWorld = Recct.createClass();
class Summary extends Component{}
3.RN所支持的最低iOS和Android版本
Android >= 4.1 (API 16)
iOS >= 7.0
4.style優先級
<View style={[styles.base, ?styles.background]}>.............. </View>
一個View可以接受多個style,如果有多個值,要用中括號 [] 括起來,最右邊的元素優先級最高,最右邊的style會覆蓋之前相同屬性的屬性值
5.屏幕寬高
(1)設置高度或寬度時不用帶單位,默認使用pt
(2)不能用百分比設置寬度高度
(3)可通過Dimensions模塊來獲取窗口寬高(可通過手動計算獲取寬高)
var Dimensions = require(‘Dimensions’);(ES6寫法改成import Dimensions from 'Dimensions';)
var {
width,
height
} = Dimensions.get(‘window’)
6.可通過PixelRatio模塊來獲取像素密度
var pixelRation = PixelRatio.get();
屏幕可以顯示的最小像素:1/pixelRation,可以用來設置border的寬度
7.render方法的注意點
(1)render() {return ();} ? return的最外層有且只有一個View,否則會報錯
(2)第一次初始化之后調用。界面呈現后,每次調用this.setState({[屬性]:[屬性值]})方法,系統都會重新調用render方法渲染視圖
8.文本換行: {'\n'}
如<Text>Hello {'\n'} World</Text>,中間會換行
9.外部文件引入寫法
ES5寫法:
(1)被引用的組件:要在文件底部有module.exports = [組件名稱];(刪掉入口函數
AppRegistry.registerComponent)。如module.exports = Header;
(2)引用的文件:const?[組件名稱] = require('./[文件名稱不帶后綴]’);,如const Header = require('./header');
ES6寫法(最新):
(1)被引用的組件:在組件前面加上export default(刪掉入口函數AppRegistry.registerComponent)。如export default class LoginUI extends Component
(2)引用的文件:import [組件] from ‘組件的路徑’; ?。如import LoginUI from './LoginUI.js';
10.引用第三方模塊相關命令:(在項目根目錄,即package.json文件所在的目錄)
npm的命令:
安裝模塊:npm i [模塊名稱] —save,如 ? ?npm i react-native-swiper —save
查看模塊:npm view [模塊名稱],如 ? ?npm view react-native-swiper
刪除模塊:npm rm?[模塊名稱] —save,如 ? ?npm rm react-native-swiper —save
查看幫助命令:nam help [命令],如 ? ?nam help i
11.TouchableHighlight、TouchableNativeFeedback、TouchableWithoutFeedback注意點
(1)均可通過onPress方法響應觸碰事件,如果還沒學會使用箭頭函數,就要加上相關函數后面bind(this),否則this.setState會出現找不到對象的情況。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 如 onPress={this.clickTarget.bind(this)}
(2)包裹內容的最外層有且只有1個對象,如果里面有多個對象,最外層用一個VIew包裹起來
(3)Text自帶onPress方法,如果不需要交互效果,如按鈕的點擊變色,可以直接用Text實現點擊事件,如
<Text onPress={this.clickTarget.bind(this)}>click me</Text>
暫時先到這里,如有紕漏,歡迎大家交流指正