[RN] 01 - Init: Try a little bit of React Native

Ref: React Native跨平臺移動應用開發html

後記:這本書博客味有點濃。前端

本篇涉及新建工程的若干套路,以及一點語法知識。java

 

 

建立新工程


(1)node

解決的一大核心問題:react

 

(2)linux

使用Javascript的嚴格模式。android

 

(3)ios

Ubuntu14.14 React Native 環境搭建
git

 

開發環境配置:程序員

ubuntu下折騰ReactNative

https://gist.github.com/platonish/f913e8a691ae811524f47bfb7710437b

 

親測,可用,開始建立工程

unsw@unsw-UX303UB$ npm install -g react-native-cli /usr/local/node-v8.9.4-linux-x64/bin/react-native -> /usr/local/node-v8.9.4-linux-x64/lib/node_modules/react-native-cli/index.js
+ react-native-cli@2.0.1
updated 1 package in 1.176s

unsw@unsw-UX303UB$ ls -a
.  ..
unsw@unsw
-UX303UB$ react-native init HelloWorld This will walk you through creating a new React Native project in /root/android-workplace/HelloWorld Installing react-native... Consider installing yarn to make this faster: https://yarnpkg.com npm WARN deprecated connect@2.30.2: connect 2.x series is deprecated npm WARN deprecated gulp-util@3.0.8: gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5 npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN react-native@0.52.2 requires a peer of react@16.2.0 but none is installed. You must install peer dependencies yourself. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) + react-native@0.52.2 added 583 packages in 37.805s Setting up new React Native app in /root/android-workplace/HelloWorld Installing React... npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) + react@16.2.0 added 1 package in 4.133s Installing Jest... npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules/fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"}) + babel-preset-react-native@4.0.0 + babel-jest@22.1.0 + react-test-renderer@16.2.0 + jest@22.1.4 added 212 packages and updated 1 package in 19.407s To run your app on iOS: cd /root/android-workplace/HelloWorld react-native run-ios - or - Open ios/HelloWorld.xcodeproj in Xcode Hit the Run button To run your app on Android: cd /root/android-workplace/HelloWorld Have an Android emulator running (quickest way to get started), or a device connected react-native run-android
unsw@unsw-UX303UB$ cd HelloWorld/ unsw@unsw-UX303UB$ react-native start Scanning folders for symlinks in /root/android-workplace/HelloWorld/node_modules (19ms) ┌──────────────────────────────────────────────────────────────────────────────┐ │ │ │ Running Metro Bundler on port 8081. │ │ │ │ Keep Metro running while developing on any JS projects. Feel free to │ │ close this tab and run your own Metro instance if you prefer. │ │ │ │ https://github.com/facebook/react-native │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Looking for JS files in /root/android-workplace/HelloWorld Metro Bundler ready. Loading dependency graph, done.
You can run the packager on another port.

$ react-native start --port=8088
Alternatively, find out what is using which ports on Windows with netstat.

$ netstat -a -b -o
Netstat gives you a PID, which you can use to kill the process.

$ taskkill /pid 1234
改變端口
有多是這兩種狀況致使的。

第一種,是沒有註冊、或者註冊語句寫錯。正確的寫法以下,引號中的AwesomeProject必定是這個項目的名稱。

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
第二種,多是8081端口被佔用。那麼如何測試這個錯誤呢?
步驟以下:

在項目文件夾中打開終端,輸入react-native start
若是在結果中出現了Packager can't listen on port 8081,那麼就證明了8081端口被佔用了。
接下去要作的是再中斷輸入命令: lsof -n -i4TCP:8081,目的是列出被佔用的端口列表
輸入命令kill -9 <PID>,目的是刪除對應PID的佔用。這裏的<PID>在第三步的端口列表中能夠找到。
輸入命令react-native run-ios從新啓動項目便可。(我本身使用的是ios,若是是andriod,那麼直接替換ios成andriod就能夠了)
果真,刪除後從新運行程序就沒有這樣的報錯了,一切正常啦!太好了!
Error:application has not been registered

 

Android Studio模擬器可能提早佔用8081,建議留給RN。

lsof -i :8081  
列出8081誰在用,而後殺掉,騰出地方。
kill -9 <PID>  

  

與服務器連接完成後,加載代碼,運行成功!

unsw@unsw-UX303UB$ react-native run-android

問題來了,js code在哪裏? Developing mobile apps with React Native in WebStorm!

以後便成了完全的網頁開發!

 

 

 

create-react-native-app


解決這個問題須要藉助兩個工具:

1. create-react-native-app(下文簡稱CRNA);

2. Expo(原名Exponent)。

 

好處:

使用 CRNA 建立 RN 應用只是不用安裝 iOS 和 Android 的編譯環境了,可是 node 仍是必須的,而後經過下面的 node 命令安裝 CRNA 這個工具。

它只包含了 JS 部分的代碼。

經過 npm start 啓動該應用後,會生成一個二維碼。

$ npm install -g create-react-native-app
$ npm start

 

可見,擺脫了react-native命令,也便是減小了對原生代碼的依賴。

 

 

 

運行Github工程


配置好 React Native

Step 1: 

Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境,其使用了一個事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。 
Node.js 的包管理器 npm,是全球最大的開源庫生態系統,功能及其強大。  

首先,在Ubuntu上安裝NPM(Node Package Manger) (avaliable)

 

Step 2:

安裝watchman: https://facebook.github.io/watchman/docs/install.html#installing-from-source

$ git clone https://github.com/facebook/watchman.git
$ cd watchman
$ git checkout v4.9.0  # the latest stable release
$ ./autogen.sh  # --> install libtool firstly, as following.
$ ./configure
$ make
$ sudo make install

 

間接安裝,brew相似於apt-get,能夠管理軟件的安裝和卸載。

Ubuntu 安裝brew【很差,貌似還須要先安裝ruby?煩】

直接安裝更好https://askubuntu.com/questions/625523/libtool-installed-but-not-on-path-after-installation

sudo apt-get install libtool

 

Step 3: 

Ref: React Native開源項目如何運行(附一波開源項目)

git clone https://github.com/poberwong/react-native-gank.git
cd react-native-gank/
npm install  <-- react-native前必須執行的一個鬼東西

 

擴展:

開源項目爲了減小空間,並無提交node_mudules目錄,須要咱們本身安裝。

unsw@unsw-UX303UB$ du -h --max-depth=1
108K	./ios
51M	./android
244M	./node_modules
76K	./jscore
7.8M	./.git
303M	.

node_modules 是整個項目的依賴, 裏面包含什麼呢?

包含的文件所有都寫在package.json 文件中了。 這個文件是必不可少的。咱們須要按照這個列表下載。 

 

React native項目是經過nodejs構建的,因此在nodejs項目中都須要package.json 文件。

具體你們能夠看看nodejs相關知識 ,七天學會 Nodejs

Goto: [NodeJS] Basic knowledge about NodeJS due to React Native

開源項目彙總
https://github.com/liuhongjun719/react-native-DaidaiHelperNew 借貸助手
https://github.com/liuhongjun719/react-native-BabyHealth- 仿寶寶健康
https://github.com/nihgwu/react-native-sudoku 數獨
https://github.com/attentiveness/reading reading
https://github.com/CoderGLM/ReactNativeLeaning
https://github.com/eesc88/programmer 雲翻譯客戶端
https://github.com/jiangqqlmj/GaGaMall 嘎嘎商城
https://github.com/879479119/Bilibili-React-Native 仿B站客戶端
https://github.com/Shuijwan/marvel漫威電影客戶端
https://github.com/talentjiang/react_native_office公司移動OA辦公客戶端
https://github.com/yohnz/maoyanFilm仿貓眼電影客戶端
https://github.com/soliury/noder-react-nativeCNode論壇客戶端
https://github.com/Kennytian/LagouApp仿拉勾網客戶端
https://github.com/SFantasy/WeiboReactNativeiOS新浪微博客戶端
https://github.com/kailuo99/toutiaoiOS資訊頭條APP
https://github.com/xiekw2010/react-native-gitfeedGithub客戶端
https://github.com/iSimar/HackerNews-React-NativeHacker新聞客戶端
https://github.com/starzhy/TheOneCoder碼農客戶端
https://github.com/tabalt/ReactNativeNews新聞客戶端
https://github.com/vczero/React-Dou豆瓣搜索客戶端
https://github.com/race604/ZhiHuDaily-React-Native知乎日報客戶端

做者:於連林520wcf
連接:https://www.jianshu.com/p/240d5ab43a48
來源:簡書
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
部分開源項目彙總

 

開始運行項目

1. 啓動虛擬機。

2. 啓動服務:

unsw@unsw-UX303UB$ react-native start

3. 加載至虛擬機並運行。 

unsw@unsw-UX303UB$ react-native run-android    
(node:4467) [DEP0022] DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead. Starting JS server... Building and installing the app on the device (cd android && ./gradlew installDebug... :app:preBuild UP-TO-DATE :app:preDebugBuild UP-TO-DATE :app:checkDebugManifest :app:preReleaseBuild UP-TO-DATE :app:prepareComAndroidSupportAppcompatV72301Library UP-TO-DATE :app:prepareComAndroidSupportRecyclerviewV72301Library UP-TO-DATE :app:prepareComAndroidSupportSupportV42301Library UP-TO-DATE :app:prepareComFacebookFrescoDrawee081Library UP-TO-DATE :app:prepareComFacebookFrescoFbcore081Library UP-TO-DATE :app:prepareComFacebookFrescoFresco081Library UP-TO-DATE :app:prepareComFacebookFrescoImagepipeline081Library UP-TO-DATE :app:prepareComFacebookFrescoImagepipelineOkhttp081Library UP-TO-DATE :app:prepareComFacebookReactReactNative0251Library UP-TO-DATE :app:prepareOrgWebkitAndroidJscR174650Library UP-TO-DATE :app:prepareDebugDependencies :app:compileDebugAidl UP-TO-DATE :app:compileDebugRenderscript UP-TO-DATE :app:generateDebugBuildConfig UP-TO-DATE :app:generateDebugAssets UP-TO-DATE :app:mergeDebugAssets UP-TO-DATE :app:generateDebugResValues UP-TO-DATE :app:generateDebugResources UP-TO-DATE :app:mergeDebugResources UP-TO-DATE :app:bundleDebugJsAndAssets SKIPPED :app:processDebugManifest UP-TO-DATE :app:processDebugResources UP-TO-DATE :app:generateDebugSources UP-TO-DATE :app:processDebugJavaRes UP-TO-DATE :app:compileDebugJavaWithJavac UP-TO-DATE :app:compileDebugNdk UP-TO-DATE :app:compileDebugSources UP-TO-DATE :app:preDexDebug UP-TO-DATE :app:dexDebug UP-TO-DATE :app:validateDebugSigning :app:packageDebug UP-TO-DATE :app:zipalignDebug UP-TO-DATE :app:assembleDebug UP-TO-DATE :app:installDebug Installing APK 'app-debug.apk' on 'Pixel_2_-_API_26(AVD) - 8.0.0' Installed on 1 device. BUILD SUCCESSFUL Total time: 10.866 secs This build could be faster, please consider using the Gradle Daemon: http://gradle.org/docs/2.4/userguide/gradle_daemon.html Starting the app on emulator-5554 (/home/unsw/Android/Sdk/platform-tools/adb -s emulator-5554 shell am start -n com.reactnativegank/.MainActivity)... Starting: Intent { cmp=com.reactnativegank/.MainActivity }

 

如此,咱們經過上手demo 相關代碼在這裏,從而瞭解【props】和【state】 這些個概念。

 

MarnoDev/HelloRN跑起來,可能需對gradle版本作些小修改,以下:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}
build.gradle
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
gradle-wrapper.properties

 

 

 

參見:給全部開發者的React Native詳細入門指南


(暫時跟着這篇學習方針走!挽救IT生涯!)

 

1、安裝WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 開發工具。目前已經被廣大中國JS開發者譽爲「Web前端開發神器」、「最強大的HTML5編輯器」、「最智能的JavaScript IDE」等。與IntelliJ IDEA同源,繼承了IntelliJ IDEA強大的JS部分的功能。

  • Ubuntu14.14須要安裝 JDK1.8 from reference

步驟:

添加軟件源
sudo add-apt-repository ppa:openjdk-r/ppa
更新源 sudo apt
-get update
安裝 openjdk
-8-jdk sudo apt-get install openjdk-8-jdk

而後就能夠切換版本:

unsw@unsw-UX303UB$ sudo update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      auto mode
  1            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1071      manual mode
  2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1069      manual mode

Press enter to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java to provide /usr/bin/java (java) in manual mode

如此,pycharm,webstorm恢復使用,激活:http://blog.csdn.net/voke_/article/details/76418116

還有記得打開755權限至少。

接下來,安裝一些插件,以及進行一些經常使用配置。好比RN組件庫的安裝,添加一些經常使用的Live Templates等。

 

  • 配置React Native

Ref: Developing mobile apps with React Native in WebStorm

 

 

2、Flex佈局

如今的 App 大多都比較簡單,無非就是佈局的展現,網絡數據的獲取等等。

這裏要說明的是,若是你是 Android 或 iOS 工程師,那你須要習慣一下 RN 處理 Json 數據的方式(或者說 Web 處理 Json 的方式),

咱們經過網絡請求回來的 Json Object 數據就能夠直接進行操做,而不像 Native 開發,還須要經過什麼額外的工具去進行 Json 的轉換。這也是 Web 開發比較方便的地方。

不管 Json Object 轉 Json 字符串,仍是 Json 字符串轉 Json Object,都是很是方便的。

若是非要把網絡數據進行本地存儲,那也很方便,經過解構賦值,直接就能夠賦值給你建立的 Model 了。

 

JSON 與 JS 對象的關係

不少人搞不清楚 JSON 和 Js 對象的關係,甚至連誰是誰都不清楚。其實,能夠這麼理解:
JSON 是 JS 對象的字符串表示法,它使用文本表示一個 JS 對象的信息,本質是一個字符串。
var obj = {a: 'Hello', b: 'World'}; //這是一個對象,注意鍵名也是可使用引號包裹的
var json = '{"a": "Hello", "b": "World"}'; //這是一個 JSON 字符串,本質是一個字符串

JSON 和 JS 對象互轉

要實現從對象轉換爲 JSON 字符串,使用 JSON.stringify() 方法: 

var json = JSON.stringify({a: 'Hello', b: 'World'}); //結果是 '{"a": "Hello", "b": "World"}' 

 要實現從 JSON 轉換爲對象,使用 JSON.parse() 方法: 

var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //結果是 {a: 'Hello', b: 'World'}
 
 

4、網絡請求(fetch

  • 傳統 Ajax 指的是 XMLHttpRequest(XHR)

XMLHttpRequest 對象提供了對 HTTP 協議的徹底的訪問,包括作出 POST 和 HEAD 請求以及普通的 GET 請求的能力。

  • jQuery 的 $.ajax 遷移到 Fetch

jQuery 是一個「寫的更少,但作的更多」的輕量級 JavaScript 庫。【將要過期的東西】

  •  Fetch的必要性 (基於promise)

XMLHttpRequest 是一個設計粗糙的 API,不符合關注分離(Separation of Concerns)的原則,配置和調用方式很是混亂,並且基於事件的異步模型寫起來也沒有現代的 Promise,generator/yield,async/await 友好。Fetch 的出現就是爲了解決 XHR 的問題。

 

  • 一個對比:
var xhr = new XMLHttpRequest();
xhr.open(
'GET', url); xhr.responseType = 'json'; xhr.onload = function() { console.log(xhr.response); }; xhr.onerror = function() { console.log("Oops, error"); }; xhr.send();

使用 Fetch 後,頓時看起來好一點:

fetch(url).then(function(response) {
  return response.json();
}).then(
function(data) { console.log(data);
}).
catch(function(e) { console.log("Oops, error");
});

使用 ES6 的 箭頭函數 後:

fetch(url).then(response => response.json())
  .then(data => console.log(data))
  .catch(e => console.log("Oops, error", e))

最終優化:

是有 Callback 的影子,而後讓咱們寫異步代碼就像寫同步代碼同樣爽;但,這是還未流行的最新的ES7方法。

try {
  let response = await fetch(url);
  let data     = response.json();
  console.log(data);
} catch(e) {
  console.log("Oops, error", e);
}
// 注:這段代碼若是想運行,外面須要包一個 async function

  

  • Fetch API 基於 Promise 設計

有必要先學習一下 Promise,推薦閱讀 MDN Promise 教程。舊瀏覽器不支持 Promise,須要使用 polyfill es6-promise 。

 Promise 對象用於表示一個異步操做的最終狀態(完成或失敗),以及其返回的值。

 這是流行的方法:ES6 的 Promise 對象,以及 test online【在線測試js代碼的地方】

then 和 catch

一個任務時

function helloWorld (ready) { return new Promise(function (resolve, reject) { if (ready) {
            resolve("Hello World!");
        } else {
            reject("Good bye!");
        }
    });
}

helloWorld(true).then(function (message) {
    alert(message);
}, function (error) {
    alert(error);
}); 

在 Promise 對象當中有兩個重要方法————resolve 和 reject

resolve 方法可使 Promise 對象的狀態改變成成功,同時傳遞一個參數用於後續成功後的操做,在這個例子當中就是 Hello World!字符串。

reject 方法則是將 Promise 對象的狀態改變爲失敗,同時將錯誤的信息傳遞到後續錯誤處理的操做。

共三種狀態:

    • Fulfilled 能夠理解爲成功的狀態

    • Rejected 能夠理解爲失敗的狀態

    • Pending 既不是 Fulfilld 也不是 Rejected 的狀態,能夠理解爲 Promise 對象實例建立時候的初始狀態

 

多個任務時

unction printHello (ready) {
    return new Promise(function (resolve, reject) {
        if (ready) {
            resolve("Hello");
        } else {
            reject("Good bye!");
        }
    });
}

function printWorld () {
    alert("World");
}

function printExclamation () {
    alert("!");
}

printHello(true)
    .then(function(message){  // tast 1
        alert(message);
    })
    .then(printWorld)      // tast 2
    .then(printExclamation);   // tast 3

In addition, 

catch 方法是 then(onFulfilled, onRejected) 方法當中 onRejected 函數的一個簡單的寫法,也就是說能夠寫成 then(fn).catch(fn),至關於 then(fn).then(null, fn)。使用 catch 的寫法比通常的寫法更加清晰明確。

 

Promise.all 和 Promise.race

 Promise.all 能夠接收一個元素爲 Promise 對象的數組做爲參數,當這個數組裏面全部的 Promise 對象都變爲 resolve 時,該方法纔會返回。

var p1 = new Promise(function (resolve) {
    setTimeout(function () {
        resolve("Hello");
    }, 3000);
});

var p2 = new Promise(function (resolve) {
    setTimeout(function () {
        resolve("World");
    }, 1000);
});

Promise.all([p1, p2]).then(function (result) {
    console.log(result); // ["Hello", "World"]
});

In addition

Promise.race,它一樣接收一個數組,不一樣的是隻要該數組中的 Promise 對象的狀態發生變化(不管是 resolve 仍是 reject)該方法都會返回。

 

 

5、props & state 

網絡請求結束後,確定是少不了數據的展現和更新。

這時又會涉及到一個很重要的知識點,就是【props】和【state】,RN中全部數據的傳遞和控制,都離不開這兩個部分。

因此,請務必在發起網絡請求前就要搞懂這兩個內容。 

在線平臺:React Native code online

Goto: [RN] React Native Practice 50 lectures

 

  

6、In the nutshell

  • 基本原理

 

  • 開發框架

From: React Native by Example

可見,就是寫js文件罷了,那麼JS的學習就成了接下來的重點 --> ECMAScript 6 入門

對於一個程序員來講,語言的學習不是個事兒!

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

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

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
  android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

export default class App 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 App.js
        </Text>
        <Text style={styles.instructions}>
          {instructions}
        </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,
  },
});

 

到此爲止,就是對當前移動開發的一些總體理解,有了知識地圖,下一步就開始步步前進!

爲何要搞這個東西?由於任何算法和技術都須要一個平臺來展現。

相關文章
相關標籤/搜索