顯示具有 RN 標籤的文章。 顯示所有文章
顯示具有 RN 標籤的文章。 顯示所有文章

2016年6月21日 星期二

React Native Redux 學習筆記

其實朋友們可以跳過這篇文章,我寫得很碎片式,只是寫給我自己看的。(如果有寫錯的地方 也麻煩留個言給我 導正我一下,目前,我還沒試出一個簡單架構出來...,也許 最近會開始嘗試吧,資料太多,暫時無法一次到位)
[粗人見解] 學習 redux 我建議去上網找一個簡單的 sample,跟著做。

2016年6月6日 星期一

React Native: CameraRoll.getPhotos(tag, success, error) is deprecated. Use the returned Promise instead

在實作 <React Native 學習手冊> 第六章時,有個 cameraRoll 的功能,cameraRoll 很白話了吧?! 就跟相片有關係的 component,其中用 getPhotos 可以取得相簿的照片。

React Native 取得地理位置 navigator.geolocation 得到 location request timed out

我的測試手機是 samsung edge plus 6.
使用 react native 版本為: ^0.26.1
在抓取 location 一直拿不到,反而一直出現 error "location request timed out".

2016年5月26日 星期四

React Native 的 android 上的 Debug JS Remotely...

在 android 模擬器上面,我找個 『Debug JS Remotely』 找超久...
官網只說要找一個 menu button... 但我的找不到...
誰可以跟我說在這個畫面上哪一個叫做 menu button...



後來 stackoverflow 發現靠指令:  adb shell input keyevent 82 
也能叫出這個 menu buttons, 真是太好了 (淚奔!)



如果你在按下 Debug JS Remotely  之後出現紅背景,建議重啟動,跑 avd 以及 react-native run-android.。


(但我的紅背景是因為 geolocation 權限還沒有加上去 XD)

參考
Intro to Debugging React Native (iOS and Android) (蠻推薦)
cmd : react-native run-android on every file change

2016年5月24日 星期二

React Native 的 Image 以及觸控

閱讀資訊:
以下文章常會見到 "RN" 字樣,我用來代表 React Native。
此文撰寫時,React Native 的版本為 0.26。
其實我也主要是在讀官方文件而已 XD 
這篇文章寫的部分你可以對應到 <歐萊禮 React Native 學習手冊> 的第四章。

樣式
React Native 偏好重複使用有樣式的元件,而非重複使用樣式。p.48 <歐萊禮 React Native  學習手冊 - 使用 JavaScript 打造原生 App.>
  • RN 的程式不能跟 React 用在 web 的共用。記得 RN 是 “Learning once, write anywhere”。
  • RN 的 componet “樣式 (StyleSheet)” 並沒有繼承的概念,除了樣式要寫在樣式物件 (StyleSheet) 之外,你可以把有樣式的元件包起來。

Image
  • 在 RN 引入圖片並不像 web 使用 img 標籤,而是使用 `<Image>`,另外屬性也不是 web img 的 src,而是 source。
  • ex: 引入 local 圖片: <Image source={require('./my-icon.png')}></Image>
  • ex: 引入外部圖片:
<Image
      source={{ uri: 'http://xxx.xx.xx/xx.png'}}
      style={{width: xx, height xx}}></Image>
  • 引入外面的圖片需要指定寬高。
  • 引入外部的圖片需指定 uri。
  • require 指定的路徑,會跟看 Javascript module 的方式一樣 (就先當作是...相對路徑)
  • 可針對平台載入同名的檔案,只要在圖檔命名上加入 platform。
  my-icon.ios.png
  my-icon.android.png

針對不同的螢幕 densities,你可能會有 @2x, @3x, 等其他的後綴檔名圖片,可以這樣擺放:
// 假設這是一個 todo 的 component 資料夾
todo
  ├── todo.js
  └── img
      ├── check@2x.png
      └── check@3x.png
然而在 todo.js 裡面的 Image 可以這樣引入 check 這個圖片
<Image source={require('./img/check.png')} />
  • 假若是 iphone5s 則會用到 check@2x (React Native 會知道要用 @2x,你無須擔心這個...,只要把 source 檔名寫好),但在 Nexus 5 會用到 @3x,若沒有適合的圖片,RN 會選最接近的來用。
  • 使用 windows 作業系統的人,假如你加入圖片到 project 下,可能需要重啟。


Image 的優點:
  1. 可同時使用在 ios, android 上。
  2. Component self-contained. 圖片跟著 component. 跟 js code 放在同一層。
  3. 沒有 global namespace 的問題。
  4. 加圖片或是換圖片無須重新編譯,只要重新整理模擬器。

官方建議,在 require 裡面的值,應該要是 statically 的,請看官方的範例:
// GOOD
<Image source={require('./my-icon.png')} />

// BAD
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />

// GOOD,把整個 require 的部分抽出來,放到 icon 變數下存取。
var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png');
<Image source={icon} />

Local Filesystem Image 本地端圖片檔案

這個本機我想指的並不是你的電腦啦,應該是實際在 run 的那隻手機上裡面的圖片。這個部分可以看 CameraRoll 就有範例可以知道如何取得 local resource.


觸控介面
  • RN 提供 TouchableHighlight 元件, 以及 PanResponder, Gesture Responder System 兩個低階 API.
  • 任何可以被處碰的 component 應該都要有 TouchableHighlight 包裝者(wrapper)。舉例來說,button 是可以被點按的地方,所以用一個 TouchableHighlight 把這個 Button 包起來。
  • TouchableHighlight 監聽 onPress 事件 (也有其他事件啦...,要看文件才知),然後你把要 callback 的 function 寫好,等著發生時觸發相對應的動作。
  • PanResponder 比 Gesture Responder System 還要高階。
  • PanResponder 提供抽象。


TouchableHighlight 範例
如希望監聽某 Image 的 touch 事件 (範例改自官網): 要注意 TouchableHighlight 只能包覆一個 子component 摟!

<TouchableHighlight onPress={this._onPressButton}>
      <Image
        style={styles.button}
        source={require('image!myButton')}
      />
</TouchableHighlight>


Gesture Responder System
  • 手機上觸控的行為非常複雜,當然不只有觸碰而已,也有可能多點觸碰或其他 (scrolling, sliding on a widget, or tapping)。而手勢回應就跟 Gesture Responder System 有關。(在官網可看到 Gesture Responder 的詳細)
  • Gesture Responder 是處理特定觸碰事件的 View。要成為一個  Gesture Responder 的 View 有幾個一定要填寫的屬性:
         (1) View.props.onStartShouldSetResponder: (evt) => true
         (2) View.props.onMoveShouldSetResponder: (evt) => true 
  • 假如其中一個回傳 true (view 會嘗試 (attempts) 成為一個 responder),以下兩個事件也會發生其中一個 (要嘛接受或是拒絕,會發生其中一個):
         (3) View.props.onResponderGrant: (evt) => {}
         (4) View.props.onResponderReject: (evt) => {} 

其實也不只這些,後頭還有很多種 Handlers 可以用。但簡單來說整個 Gesture 的生命週期是: 開始 -> 移動 -> 釋放。所以你會很常看到 handlers 的名稱含有 start, release, move...等字樣。

Gesture Responder 具有冒泡事件的特性,如果要覆寫這些行為,可在父元件將
View.props.onStartShouldSetResponder, View.props.onMoveShouldSetResponder 回傳 true。


觸控事件發生之後,相關的 handlers 也會被呼叫。被呼叫的時候會接收 evt (nativeEvent) 參數,有很多屬性值可以取得,如觸碰的 ID, 觸碰元素的 x,y 軸座標,時間... 等等。

參考自官方文件:

identifier - The ID of the touch
locationX - The X position of the touch, relative to the element
locationY - The Y position of the touch, relative to the element
pageX - The X position of the touch, relative to the root element
pageY - The Y position of the touch, relative to the root element
target - The node id of the element receiving the touch event
timestamp - A time identifier for the touch, useful for velocity calculation
touches - Array of all current touches on the screen
(source from: https://facebook.github.io/react-native/docs/gesture-responder-
system.html#content)

PanResponder
PanResponder 提供比較高階的 api 處理單點與多點觸控,也能存取原始的事件 (nativeEvent)。他的用法主要是透過 gestureState 可以得到一些你可能有需要的資訊:

  • stateID (只要螢幕上有至少一個碰觸)
  • moveX, moveY (最近一次觸碰移動的螢幕座標)
  • x0, y0
  • dx (從碰觸開始累計手勢的距離)
  • dy
  • vx (目前手勢的向量)
  • vy
  • numberActiveTouches (螢幕上碰觸的數量)

用法: 建立一個 PanResponder 的物件,你要準備一些 callback function。然後在 render 的方法中使用他。

componentWillMount: function() {
    this._panResponder = PanResponder.create({
      onStartShouldSetPanResponder: (evt, gestureState) => this._handlePanResponder,
      onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
      onPanResponderGrant: (evt, gestureState) => {},
      onPanResponderMove: (evt, gestureState) => {},
      onPanResponderTerminationRequest: (evt, gestureState) => true,
      onPanResponderRelease: (evt, gestureState) => {},
      onPanResponderTerminate: (evt, gestureState) => {},
      onShouldBlockNativeResponder: (evt, gestureState) => {},
    });
  },

  render: function() {
    return (
      <View {...this._panResponder.panHandlers} />
    );
  },


結語

  1. 提供一般元件的觸碰回應,使用 TouchableHighlight。
  2. 自訂觸碰介面或是較複雜的應用如遊戲類,使用 PanResponder, Gesture Responder System。

參考

React Native 如何跑在 android 實機上測試 (Draft...)

主要參考 : https://facebook.github.io/react-native/docs/running-on-device-android.html#content

注意: 這裡不介紹 android 需要哪些環境及安裝,假設你環境都已ok,且在本機的模擬器也跑得起來。

  • 若有開模擬器,可先關掉 avd。
  • 手機要 enable USB Debugging。 (無法教你,看個人手機設定如何,請 google)
  • 把你的手機插上電腦。
  • 使用 adb devices 指令確認電腦知道這個 Physical device。
  • 重新 run 一次 react-native run-android。
  • 若出現紅色畫面,有出現 Reload JS 就按按看。
  • 還有問題的話嘗試執行 adb reverse tcp:8081 tcp:8081,再按一次 Reload JS。

其他好文

React Native for Android 入门老虎
[教學] React Native for Android - 1: 基礎

React Native: In next release empty section headers will be rendered... 訊息

完整訊息:

In this release you can use 'enableEmptySections' flag to render empty section headers.


在 ListView 加上 enableEmptySections={true} 的屬性,忽略這個 warning.


參考:
https://facebook.github.io/react-native/docs/listview.html
https://github.com/FaridSafi/react-native-gifted-listview/issues/39

2016年5月23日 星期一

React Native 學習手冊 讀書筆記之第三章

註: 書本資訊: 歐萊禮 React Native  學習手冊 - 使用 JavaScript 打造原生 App.
Bonnie Eisenman 著 / 楊尊一 譯

以下文章常會見到 RN 字樣,我用來代表 React Native。

照著官方網站安裝 RN 的開發環境,假如你是利用 homebrew 你可能會走以下流程: (我只大概 brief 一下而已,請以官方文件為主。)

你也可以參考我的另外一篇文章 http://winwu.github.io/react-native-note/2016/04/25/native-02/,撰寫於 2016/4, 如果你看這篇文章已經離這個日子有點久了,那就不要看了 XD 因為我並沒有把握 RN 多久更新一次安裝的方法之類的...。


brew install node
brew install watchman
brew install flow

//optional start (可執行可不執行,看你自己)
brew update
brew upgrade
//optional end


// 安裝 recat native 的 commandLine 指令工具
npm install  -g react-native-cli

// 接下開始依照你要開發的平台安裝不同開發環境
// ios 相依或是 android 相依

總體來說,如果你是 mac 電腦, ios 的環境較簡單,android 比較複雜,倘若你也尚未接觸過一些 app 開發的 know how 的話,環境也許會耗掉你蠻多時間的 (<- 苦逼過來人 Orz)。
  • React Native 套件會用到 node 跟 watchman,如果這兩個套件有帶給你什麼麻煩,請你重新更新這些 package 的相依性試試看。
  • flow 是 Facebook 檢查型別的函式庫。

利用 React Native Cli 建立新的應用程式

這是一個會需要等一下的指令...
react-native init FirstProj

這是目錄:
.
├── android
├── index.android.js
├── index.ios.js
├── ios
├── node_modules
└── package.json


而 index.ios.js, index.android.js 是程式的進入點。


探索範例程式
  • ios 專案可用 xcode 開啟,有支  AppDelegate.m 的檔案可以詳讀。
  • 看到 RTC 開頭的類別,即代表 React Native 的類別。
  • jsCodeLocation 則是未來要部署到實體裝飾可能會修改的設定。(詳細在註解看得到)
  • 有個 moduleName (例: moduleName:@"FirstProj") 的設定在未來也有機會改到他。
  • moduleName 會對應到一個同名的 React 元件,開啟 index.ios.js 會看到一個登記頂層 component 的設定:
     
    AppRegistry.registerComponent('FirstProj', () => FirstProj);
意思是暴露 FirstProj 讓 AppDelegate 可以使用它。其實你也不太會去修改這項設定。

而 Android 則要看 MainActivity.java (如果你有 android studio 可以開來看一下)。登記進入點的地方為 `mReactRootView.startReactApplication(mReactInstanceManager, "FirstProj", null)`。

RN 的 Import
// index.ios.js
  7 import React, { Component } from 'react';
  8 import {
  9   AppRegistry,
 10   StyleSheet,
 11   Text,
 12   View
 13 } from 'react-native';



  • RN 要求你必須明確的 import 每個你會用到的組件,最常用的為 StyleSheet, Text, View 等等。
  • RN 沒有 <div> 這種標籤,通常我們會用 <View>, <Text> 類似於 <div>, <span>。


這章節有個實作小練習,貼心提醒:
  1. 使用 http://openweathermap.org/ 的 API 請先註冊,註冊後請找到你的 APP ID,這很重要,以防你跟著範例卻要不到資料 (一般來說你會拿到 401 的錯誤碼),因為你 fetch 發出去的 api 沒有權限。 
  2. 拿到 APP ID 後把 APPID 的參數加到 fetch 的 url 後綴,如: http://api.openweathermap.org/data/2.5/ .....&APPID=YOURAPPID



有個地方教你如何加入圖片檔案,但如果新的 xcode,位置在此:
(不過這個方法我試了沒有成功,最後我是把圖片放在根目錄 img 底下,用相對路徑去拿)

2016年5月22日 星期日

React Native 學習手冊 讀書筆記之第二章

書本資訊: 歐萊禮 React Native  學習手冊 - 使用 JavaScript 打造原生 App.
Bonnie Eisenman 著 / 楊尊一 譯。如果你有興趣讀一讀請多購買書籍。這本書寫得不錯!

以下文章常會見到 RN 字樣,我用來代表 React Native。

第二章主要說明 RN 的運作方式,不會寫的太難,但我會試圖把一些中文翻譯改用英文寫筆記,例如假如我寫到 "元件",可能有時候會用 "Component" 表達。

說真的,用 JavaScript 來寫 Mobile App 我真的覺得很怪...

  1. 理解 RN 的底層技術,第一件要先想到 React 的功能之 ~ Virtual DOM.
  2. Virtual DOM: 沒有 virtual DOM 的時候,以前的 DOM 的渲染與更新是一個成本很高的步驟,大量的 DOM 甚至會造成效能的影響,簡單一句話就是『js 很快但 DOM 很慢 』,相較於此,React 使用記憶體版本的 DOM,計算必要的改變,只顯示有需要改變的 DOM。

    這背後的演算法到底是如何我其實也不是很懂...  (另外什麼叫做記憶體版本... 我也不是很懂,若有人知道方便留言一下嗎 ><  我目前是猜在記憶體算一算在 render 出來)
Virtual DOM 三步驟:
狀態改變 -> 計算差異(diff) -> 重新顯示有差異的 DOM。

因為 Virtaul DOM 在效能上帶來好處,這也就是為什麼它很厲害的原因吧。
你可以參考這些文章,或是自己 google,Virtual DOM 出來好一陣子了,現在文章應該很多: 



RN 會呼叫 Objective-C,  Java 的 API 來顯示 UI 元件 (element)。RN 會把對應的標籤(元件),轉換為符合平台的元件,所以像是 <View> 這個標籤在 ios 上會被轉為 <UIView>。


React Native currently supports iOS and Android. Because of the abstraction layer provided by the Virtual DOM, React Native could target other platforms, too—some‐ one just needs to write the bridge. - Learning React Native  p.9

意思就是,RN 支援 ios/android, 而且抽象層是 Virtual DOM,  因此 RN 也可以針對其他平台,只要有人寫出那個 Bridge(橋接) 來。


顯示的生命週期

RN 的顯示生命週期跟 React 大部分相同,唯一的不同在於顯示的部分需要橋接 (你就當作 bridge),轉譯 JavaScript 並呼叫平台底層的 UI 元件。


在 React Native 中使用 Component


  • RN 使用的 component 跟 React 不同,大部分元件都有特定的元件名稱,少數必須針對不同平台,如 NavigatorIOS。
  • 平台專屬的元件名稱有特定命名規則 (主要是放在後綴),如 XXXXAndroid, XXIOS。
  • 你可以參考 UIExplorer,裡面有各種 component 應用的 UI 樣子 (https://github.com/facebook/react-native/tree/master/Examples/UIExplorer),clone 下來跑跑看...。
  • 以 NavigatorIOS 來說,很顯然它不能在 Android 上使用,還好顯示用的元件是可以根據平台做替換的,你也可以指定平台專用的元件,例如 nav.ios.js 以及 nav.android.js。

關於 JXS

jsx 重視分離關注高於分離技術。 page 10.

(在 React 剛開始時,大多數的人對於把 HTML/CSS/JavaScript 寫在一起感到疑惑...(me, too...),甚至有的人是因為不喜歡 html 夾雜在 JavaScript)。


  • RN 因為是在一個沒有瀏覽器的世界中。(要注意有些東西不存在於 RN 中,如 <div>)。
  • RN 的 .js 其實實際上可以說是 JSX 檔案。(開發 React Native 是一定會用到 jsx 的)。
  • RN 中撰寫 CSS 需要使用物件樣式來表示,只是用 Object 來表示,久而久之會習慣啦!,有些 CSS 的設定會受到限制,你不是在寫 web,主要的 CSS 佈局會以 Flexbox 為主。但是有些連著的單字需要以小駝峰式命名法(lower camel case)表示 (第一個單字以小寫字母開始;第二個單字的首字母大寫),例如在 web 上的 css 背景顏色會用 background-color,但在 RN 的 CSS 表達則要轉換為 backgroundColor,其他的也是,會變成 fontSize, marginBottom, textAlign...。


React Native 學習手冊 讀書筆記之第一章

書本資訊: 歐萊禮 React Native  學習手冊 - 使用 JavaScript 打造原生 App.
Bonnie Eisenman 著 / 楊尊一 譯

以下文章常會見到 RN 字樣,我用來代表 React Native。

React Native 是什麼?
  • 基於 JavaScript 撰寫真正的行動應用程式。
  • 而 React Native 為 Facebook 開發出來的一套 JavaScript 函式庫,用來同時開發 Android 以及 IOS。它以 JavaScript 以及 JXS 混合撰寫,然後 RN 在底層以 Objective-C 或 Java 幫你橋接原生 API 的呼叫。
  • 目前已經使用 RN 用來打造行動應用的有:
    •  Facebook
    •  Palantir
    •  TaskRabbit

RN 的優點

過去 Web 應用程式使用 HTML/CSS/JavaScript 來作出手機應用,模擬很多在手機上的 UI,但還是無法做到存取原生平台的 UI 元素。雖然模擬這些原生的 UI 沒有什麼不對,但動畫等細節非常耗時 (工程師的開發時間),而且容易過時。


而 RN 可以:
  • RN 利用標籤幫你轉換成真正的原生 UI 元件。 (這裡指的標籤不是 HTML 標籤,而是一些 (盡量) 符合原生 UI 的標籤名稱)。
  • RN 的工作與主要的 UI 元素執行緒分離。
  • RN 的更新週期與 React 的運作方式相同 (props, state 改變的話,RN 也會重新更新畫面)。
  • 除錯可以直接使用瀏覽器的除錯工具。 (如: `Chrome Debugger`)。
  • RN 的開發環境對一般 Web 開發者還蠻友善的。並不需要 (強迫) 你使用 xcode 或 Android Studio.
  • (有點重要) RN 對產品發佈有方便之處。 Apple 允許透過無線載入 JavaScript 基礎的應用程式行為修改 (<- sorry, 我也不知道這是什麼意思),方便的意思就是有了這個優點你不需要經過額外的審查。
          或許可參考看看:




RN 的缺點

  • 不是所有的程式都可以共用 for IOS/Android. 特定平台需要的功能需要額外撰寫 Java/objective-C。 (但大部分的程式是可共用的。以 Faceboook Ads Manager app 來說,android/ios 共用的程式可達 87%)
  • 還太年幼,RN 目前最大的風險是成熟度,文件, 功能的支援還在改善中。



這本書我期待已久,因為之前看了一本雷書...
關於其他的 React Native 筆記,你可以參考看看我的 React Native 學習之旅。 http://winwu.github.io/react-native-note/ ,或是期待我惰性未發的下一篇....

Vue multiselect set autofocus and tinymce set autofocus

要在畫面一進來 focus multiselect 的方式: 參考: https://jsfiddle.net/shentao/mnphdt2g/ 主要就是在 multiselect 的 tag 加上 ref (例如: my_multiselect), 另外在 mounted...