ReactNativeにNativeBaseを導入してUIを整える
概要
天気の情報を入れた、が! CloudsとかClearとか言われてもわけわからん! いつの天気!? みたいに思うのでとりあえずUIをそれっぽくしてみようと思った。
前回:
情報設計
L2. いつ L1. 天候 L3. 気温, 湿度, 気圧 L4. 更新
対応フロー
実装調査
起動時初期化
ContainerでcomponentDidMount
時にasyncAction発行すれば行けそう。
UI
他のMaterial系とかも探したけど、 ここ数ヶ月でメンテされてて、情報がありそうなフレームワークがぱっと見みつからなかった。
そういうの探すのにおすすめな記事とかあれば知りたい。 そういうの探すのにおすすめな記事とかあれば知りたい。(こういうのとか)
Comonents
まあこの辺使えばいけるんじゃないの?的なやつ。
- Layout Components · NativeBase
- Header Components · NativeBase
- Spinner Components · NativeBase
- Button Components · NativeBase
- Icon Components · NativeBase
実装
- API通信が「取得」から「読み込み(自動)」「再読込(ユーザアクション)」に別れたことで、UseCase, Action, Reducerに変更が必要となった
- めんどくさくてUseCaseだけ分けた
- あとで違うインタラクションにしてくれって言われたときに困るかもしれない
- ローディングの有無とか、表示の仕方とか
- 困らないかもしれない
- Viewから見て別れていれば一旦おk
- いやこれ、絶対あとで「クソだろ」って思う
- react-baseがコケた
Error: Unable to resolve module 'create-react-class'
- NativeBaseでReactNativeのComponentを置き換え
- NativeBaseでアイコン利用
- type, name を指定するが、☓になる
- 名前を変えても☓
react-native link
してなかった- デフォルトはIonicons
- ボタン+アイコンがいい感じの配置にならない
- ドキュメントのコードとキャプチャが違う
- サンプルを示してくれ!!!!
Error: Unable to resolve module create-react-class
Loading dependency graph, done. error: bundling failed: Error: Unable to resolve module `create-react-class` from `/Users/mizuki/project/rnapp-weather/node_modules/native-base/dist/src/basic/Picker.android.js`: Module `create-react-class` does not exist in the Haste module map
インストールで解決。
$ npm install --save create-react-class
NativeBaseの利用
$ npm install --save native-base $ react-native link
Android EmulatorのScreen shot
$ adb shell screencap -p /sdcard/screen.png $ adb pull /sdcard/screen.png /tmp/screen.png $ adb shell rm /sdcard/screen.png $ open /tmp/screen.png
参考: MacでAndroid開発中に手軽にスクリーンショットを撮る
完成図
React Native に Reduxを加え、ロジックを実装する
概要
React Native入門シリーズその3。 Reduxを導入してAPI通信してViewに引き渡す。
前回: ReactNativeにTypeScriptを導入する - のらねこの気まま暮らし
APIについて
OpenWeather
アプリについて
今回試すことが主軸にあって、 「こういうView」っていう提案まで考えてない。よって実用的ではないものだが、アプリの構成について考える土台として雑に作る。
インタラクション
本来なら、今の天気を取得しつつ予報も出すべきだが前述の通り手抜きで対応する。
- ボタンを押したら、天気の読み込みが始まる。
- 天気の読み込みが完了したら、天気の情報を表示する。
View設計
- 今の天気を取得するボタン
- 天気の状態をそのまま表示
アーキテクチャ
アプリの構造を考えるぞい。
選定
- Redux Way
- Redux Way Arrange
- Ducks
Redux Way系は役割でコードを分ける、Ducksは関心でコードを分ける。
個人的にクライアントの関心はViewの側面から見たActionとアプリ全体から見たStateに分けられると思っていて、そこを密結合することに懸念がある(実際、Vuexでも結構悩んだ)。
今回はReduxについて真剣に考えるより、React Nativeを知ることが目的なので複雑な悩みを抱えたくない。
しかし、Redux Wayは僕の感覚に則さない...
ということで感覚的にしっくり来るようにRedux WayをArrangeする。
Redux Way Arrange
View層
React Componentを配置する。 Container,Presentational,AppRootを管理する。
UseCase層
Viewから入力を受け取り、dispatchのタイミングを制御する。 いざ名乗ってみると違和感しかない。 Containerと対応する。
Action層
ActionCreator。
UserCaseで構築したデータをActionにパッキングする。 ここはもっと隠蔽できると嬉しい。
究極、s2sとか使って自動生成したい。
Store層
Redux Storeの初期化と、Reducerの定義を担う。 Reducer基本的にStoreからしか参照されないしっていうかStoreの一部だよね、の気持ち。
ReducerはViewではなく、アプリ内のドメインと対応する。 Stateはアプリにおける情報のドメイン。
Service層
名前に悩んだけどまあとりあえず。
外部APIとの通信、アプリへの最適化を担う。 だいたい外部APIを使う場合(それが自前で用意したAPIだとしても)要求以上の実装がされがちなので、そういう本質的ではないが必要なことをまとめておく場所。
基本的にUseCaseからしか呼ばれない。
実装フロー
事前想定:
- 天気取得ボタンの作成
- 天気取得のUseCaseの作成
- Reducerの雛形
- OpenWeather API取得の実装
- UserCase内でAPI呼び出し
- weather用のReducerを定義
- ViewにReducerから取得したデータを表示
実際:
- React + Reduxの雛形作成
- ボタンの作成
- 天気取得のUseCaseの作成
- Actionの作成
- Reducerの作成
- 型の定義(Action, State, Props, etc)
- Weather用のReducerを定義
- ここでContantsが必要だと判断
- OpenWeather API取得の実装
- weatherのReducerに実データとローディングフラグを実装
- Viewに読み込み時の処理と天気表示を実装
つまったところ
connect
の実装と型定義Object.assign
の引数の順番間違えた- OpenWeather APIの仕様調査と型定義
モジュールの変化
core
- react-redux
- redux
- @types/react-redux
- @types/redux
service
- axios
- qs
- @types/qs
所感
TypeScriptの警告つぶしが結構面倒だった。 Reducer定義しないといけないことを知った。 OpenWeatherAPIの仕様以外と知らなくて手間取った。 土台ができちゃえばあとは継ぎ足しで行けるかなって思った。 あれ、ReactNativeってなんだっけ?
ReactNativeにTypeScriptを導入する
概要
前回の続きです。 できたてホヤホヤのプロジェクトにTypeScriptを導入する。
環境
- react v16.3.1
- react-native v0.55.2
- react-native-cli v2.0.1
依存モジュールのインストール
$ npm install -D \ typescript \ node-libs-react-native \ react-native-typescript-transformer \ @types/react \ @types/react-native \ @types/jest $ npm audit fix
tsconfigの設定
{ "compilerOptions": { "target": "ES2017", "module": "ES2015", "jsx": "react-native", "rootDir": "./src", "strict": true, "skipLibCheck": true, "noImplicitAny": true, "noImplicitThis": true, "alwaysStrict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "moduleResolution": "node", "baseUrl": "./", "esModuleInterop": true, }, "include": [ "src/**/*" ], "exclude": [ "node_modules" ] }
CLIにTransformをフックする
const extraNodeModules = require('node-libs-react-native') module.exports = { extraNodeModules, getTransformModulePath() { return require.resolve('react-native-typescript-transformer'); }, getSourceExts() { return ['ts', 'tsx']; } }
App.jsを書き換え
import { Component } from 'react'; import { StyleSheet, Text, View } from 'react-native'; export default class App extends Component { render() { return ( <View style={styles.container}> <Text>Open up App.js to start working on your app!</Text> <Text>Changes you make will automatically reload.</Text> <Text>Shake your phone to open the developer menu.</Text> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
$ rm App.js
実行
$ npm run start
$ npm run android
初心者がReactNativeを使ってAndroidで起動できるようにするまでの記録
概要
諸事情でReactNative触る機会があるんだけど、 Nativeは経験が薄く、Reactもそんなにガッツリ触ってないのでこれを期に勉強しようと思ったのでまとめ。
実行環境
- Mac mini (Late 2014)
- OS X EL Capitan
- 2.8 GHz Intel Core i5
- 8GB
悲しいかな、High Sierraにできなかったんだこの端末...
入門準備
めんどくさいので今回はAndroidのみ。
Android
SDKMan
JDKや管理用にSDKMANを入れる。
Home - SDKMAN! the Software Development Kit Manager
$ curl -s "https://get.sdkman.io" | bash $ source "$HOME/.sdkman/bin/sdkman-init.sh"
※このとき、tr
, tt
にshellでalias貼ってるとエラーになるので注意。
~/.bashrc
を開くとSDKMANの初期化コードが含まれている。(えーーーー)
zsh使いなのでzprofileに移す...
$ echo ' #THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!! export SDKMAN_DIR="/Users/mizuki/.sdkman" [[ -s "/Users/mizuki/.sdkman/bin/sdkman-init.sh" ]] && source "/Users/mizuki/.sdkman/bin/sdkman-init.sh" ' >> ~/.zprofile
いや、よしんばbashはいいとしても、rcに書き込まないでくださいよ、こちとらgitで管理してんやぞ? profileあるやろ。なんで?
.zprofile
はお使いのshellに置き換えてご利用ください。
$ sdk version SDKMAN 5.5.13+272
JDKのインストール
$ sdk list java
一覧が出てくる。 今回は諸事情によって1.8が使いたい。
$ sdk install java 8.0.171-oracle
$ java -version java version "1.8.0_171" Java(TM) SE Runtime Environment (build 1.8.0_171-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
ok
Android Studio
Download Android Studio and SDK tools | Android DevelopersからAndroidStudioをダウンロードしてくる。
(この時点での最新は3.1.3 for Mac
)
インストール類は時間かかるから先にやるのがおすすめ
ReactNativeのガイダンスに従ってインストールを進める。
- ウィザードが起動するので、Choose the type of setup you want for Andriod Studio のメッセージが出てきたら
Custom
を選択。 - Select UI Theme は好きなやつ
- SDK Components Setupは以下のものを選ぶ 3.1. Android SDK (チェック済み) 3.2. Android SDK Platform (チェック済み) 3.3. Performance (Intel ® HAXM) (チェック済み) 3.4. Android Virtual Device (チェックする)
- このさきは任意で
Android Virtual Device はエミュレーターのやつ。
ウィザードが完了したら Welcom to Android Studio 画面に来るので、Configure から SDK Manager を起動。
なんかいい感じに選んでいれてく。
最後にANDROID_HOME
にパスを通す。
$ echo ' export ANDROID_HOME=$HOME/Library/Android/sdk export PATH=$PATH:$ANDROID_HOME/tools export PATH=$PATH:$ANDROID_HOME/tools/bin export PATH=$PATH:$ANDROID_HOME/platform-tools ' >> ~/.zprofile
あとでadbとか使うからね。
ReactNative Projectのセットアップ
$ npm install -g create-react-native-app $ create-react-native-app rnapp-weather
Node実行環境
$ ndenv install v10.5.0 $ ndnev local $ ndenv rehash # create-react-native-appで入ったやつを消 $ rm -rf node_modulesす $ rm yarn.lock # re:install $ npm install
added 1302 packages from 787 contributors and audited 35887 packages in 55.633s found 5 vulnerabilities (2 low, 2 moderate, 1 high) run `npm audit fix` to fix them, or `npm audit` for details
npm 6で追加されたauditのレポート。
npm audit fix
を使うと、解決策が提示されている場合は解決してくれる。
+ react-native-scripts@1.14.1 added 6 packages from 17 contributors, removed 82 packages and updated 4 packages in 12.801s fixed 2 of 5 vulnerabilities in 35887 scanned packages 2 vulnerabilities required manual review and could not be updated 1 package update for 1 vuln involved breaking changes (use `npm audit fix --force` to install breaking changes; or do it by hand)
一旦これでよしとしよう。
実行
$ npm start
10:20:11: Unable to start server See https://git.io/v5vcn for more information, either install watchman or run the following snippet: sudo sysctl -w kern.maxfiles=5242880 sudo sysctl -w kern.maxfilesperproc=524288
なるほど
$ sudo sysctl -w kern.maxfiles=5242880 $ sudo sysctl -w kern.maxfilesperproc=524288
リトライ
$ npm start 10:22:03: Starting packager...
okそう。
ejectの実行
このままだとReactNativeしかないのでNative使えるようにする
$ npm run eject > rnapp-weather@0.1.0 eject /Users/mizuki/project/rnapp-weather > react-native-scripts eject We didn't find any uses of the Expo SDK in your project, so you should be fine to eject to "Plain" React Native. (This check isn't very sophisticated, though.) We strongly recommend that you read this document before you proceed: https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md Ejecting is permanent! Please be careful with your selection. ? How would you like to eject from create-react-native-app? React Native: I'd li ke a regular React Native project. We have a couple of questions to ask you about how you'd like to name your app: ? What should your app appear as on a user's home screen? Weather ? What should your Android Studio and Xcode projects be called? Weather
How would you like to eject from create-react-native-app?
そのままEnter
What should your app appear as on a user’s home screen?
Weather
What should your Android Studio and Xcode projects be called?
Weather
Android端末の接続
手元にないのでエミュレーターで。 ーーって思ったけどどこからDevice Manager起動するのかわからねえ...
仕方ないので新しくProject立ち上げる。 CLIとかどっからDevice Manager起動できひんの?
Virtual Devices起動できた、が、アイコン小さすぎてわからない。これは... 初心者辛くない...?
$ adb devices List of devices attached emulator-5554 device
接続を確認。
AndroidでReactNativeを実行
$ npm start
こっちでビルドして配信する。
別ターミナルを開いて、ビルドを実行。
$ npm run android
めったビルド走る。
わぁい赤ぁい
error: bundling failed: Error: Couldn't find preset "babel-preset-react-native-stage-0/decorator-support" relative to directory "/Users/mizuki/project/rnapp-weather"
diff --git a/.babelrc b/.babelrc index 0f0c07d..57415c7 100644 --- a/.babelrc +++ b/.babelrc @@ -1,6 +1,6 @@ { "presets": [ - "babel-preset-react-native-stage-0/decorator-support" + "babel-preset-react-native" ], "env": { "development": {
うごいた
Hello World
しようとおもったけど疲れたので次にする。 hotreloadうごかん。
まとめ
導入で力尽きた
- create-react-native-appしたらejectする
- モジュール間のバージョン際なんてよくあること
- emulatorはなにが起きてもおかしくないので強く心を保つ
- hotreloadをする
3hくらいかかった。つかれた
React+Redux覚書
概要
React+Reduxを使ってアプリを書く機会があったが、 どちらもちゃんと触ったのは年単位昔なので思い出すために軽くコードを書いてみた。
ーーやつの備忘録。
こういうことを思ってこうしたいなって気持ちになったという記録。
基本構成
environment
- Docker node:10.4.0-alpine
dependencies
- react 16.4.1
- react-redux 5.0.7
- redux 4.0.0
devDependencies
- babel-loader 7.1.4
- babel-preset-react 6.24.1
- webpack 4.12.9
基礎知識
- React
- Redux
- connect
- state
- reducer
- Component
- Provider
- Container
- Presentational
所感
もともとSyntagme作るときに、Reduxのコードは読んでいたので一度読み直せば「あーはいはい」って感じだった。
ただ、当時思ったActionCreatorの扱いでやっぱり戸惑う。
ActionCreatorは、 * dispatchするオブジェクトを作る * 複雑なdispatchを隠蔽する
の役割があると感じていて、 その2つを共存させることに抵抗がある。
できれば役割わけたいなぁと。
もしかしたらMiddlewareがいい感じに隠蔽してくれるのかも知れないが、 初心者にはその歴史的経緯をさっくり理解するにはReduxの世界は広すぎる。
再設計
というわけで腹落ちする程度まで掘り下げた。
ディレクトリ構成
- src +- index.js +- views/ | +- components/ | +- containers/ | | +- Home.jsx | +- App.jsx +- usecase | +- home.js +- actions/ | +- index.js +- store/ +- index.js +- reducers/
index.js
App.jsx
のマウント- アプリケーション全体の初期化処理
Views
React Componentを押し込める場所。 汎用的なものだけではなく、画面構成全部を含むので、Viewって名前空間にした。
App.jsx
- Providerの構築
- Redux Storeとの接続
Containers
- Container Componentの置き場
- Presentationalを一つ以上組み合わせる
- ViewとUseCase, Stateを接続する
Components
- Presentational Component
- コンテキスト持っちゃ駄目よ
- 小規模ならこれでいいけど、Componentの数が増えてきたらAtomic-Designとかをベースに分割したほうがいいかもしれない
- が、必要ないならしないほうが無難
UseCase
- 独自定義
- 着想はAlminから
- view ← 何らかのイベント → action の中間処理を担う
- fluxで言うところのActionCreator
- view側からの入力のハンドル
- アプリの外側とのコミュニケーション
- dispatchのタイミングのハンドル
- 基本的にはContainerと対応する
Actions
- Actionオブジェクトの作成
- 程よい切り方がわからないけど機能単位で切るのがいいのかなぁ
Store
Redux Storeの定義。
index
- createStoreの実行
- reducer, initialState, middlewareの構築
initial-state
- 初期Stateの定義
reducers
- reducerの定義
- 基本的にはアプリケーションにおける情報設計単位でファイルを切る
まとめ
- React+Reduxで最低限腹落ちする構成を考えた
Macを外部ディスプレイにつなげた時のWindow配置を記憶したい!
背景
最近の僕は、GoogleChromeのタブを38個とか開いているようです。
Tabs Outliner と Spaces という拡張機能を併用して、 たっくさんあるタブを用途やカテゴリ毎にwindowに分割しているんです。
まあ、ぞれでもWindowは5,6個できるんですけど。
Tabs OutlinerとSpacesのおかげで管理は大分楽になったんですが、困ったことが一つありまして。
問題
普段はMac Bookを外部ディスプレイにつなげて普段作業しているんですよね。Mac Bookのディスプレイと外部ディスプレイ二枚。
会議や相談なんかあれば、外部ディスプレイの接続切ってMac Bookを持っていくわけです。 そして話し終えたら席に戻ってきて外部ディスプレイに接続する。
画面にでてくるのは、SlackやiTerm、そして5,6個重なったGoogle Chrome。
微妙に位置を調整して、ワンクリックで目的のWindowを開けるようにしていたGoogle Chromeの位置を戻すのがもう、面倒でしかたないったらありゃしない。
さすがに、疲れました。
調査
そんなわけで、頼れるGoogle先生に聞いてみたんです。できないかって。
参考になったのは、以下の記事でした。
forget-me-not
は残念ながらアクセス出来ませんでした。まあ2012年の記事だし。
代わりにStay の方を見てみました。
AppStoreで\1,800だったので、即買。
検証
先ほどの StayさえあればもうMBAをサブディスプレイに繋げるのは怖くない を見ながら設定してみました。
2,3回試しました。繋いで、はずして。
Google ChromeのWindow7枚とiTermとSlackだけ個別にstoreしてみました。 Mac Bookを開いたままコネクタを外すと、まあ位置画面に収まります。 そのまま繋げ直してみると、「Restoring windows」と表示されてガチャガチャwindowのサイズや配置が変わっていきます。
結論
なにこれ便利...!
お試しあれ
参考
2015年の振り返り
新年早々いろいろあって振り返ってる余裕が無かったので、それっぽいのをハリボテで。
2015年に書いた記事
当ブログ
8記事!少ない!!
Qiita
2記事!少ない!!
2015年に発表したトーク(public)
www.slideshare.net
www.slideshare.net
www.slideshare.net
www.slideshare.net
4回!ま、まあ...
振り返り
JavaScript一色だなぁ...
ブラウザサイドからNodeJSまで。 ただ、使っているツールや関心の範囲はこの一年でだいぶかわってきたのかなと思う。
フロントエンドツールの開拓、WAFのアーキテクチャ設計、それに関連する各種ライブラリの選定等など、外部モジュールを触るのが多い一年だった。 MVCよくわからんっていう時期から、FluxやReduxを通じてアプリのアーキテクチャを考えていく中で、 単一のライブラリに頼るのも、複数を組み合わせるのもそれなりに模索が必要だと感じているのが年末だった。
2016年の抱負
ツールは揃ってきているけど、いま欲しいものが現状ない。 そういう「何がほしいのか」という部分を自分が適切に理解し、それに即したライブラリを模索・制作していきたいなとは思っている。
年が明けてから、FluxやReduxによって手放そうとしたMVC,DDDを取り戻す方向性を考えている。 技術的にModelとはどういうものか、というより、Model的な考え方をFlux上に載せつつ、効率的に開発できないかと考えている最近。
僕はもともとMVCについての理解が浅かったので、改めて勉強しようかなと思う。
余談
新年早々部屋が半分水浸しになって大変大変つらかったけど、この先は楽しい一年にしていこうとおもったのでした