Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Our choice in ReactNative
Search
joe_re
May 19, 2017
Technology
32k
8
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Our choice in ReactNative
https://react-native-meetup.connpass.com/event/53572/
発表資料
joe_re
May 19, 2017
More Decks by joe_re
See All by joe_re
Eyes on Claude Code
joere
0
150
Building Public API with GraphQL
joere
3
160
Traversing the GraphQL AST and Calculating Query Costs
joere
0
1.3k
Real-Time applications with GraphQL
joere
0
320
Prisma2 with Graphql
joere
3
1k
Go beyound static on Netlify
joere
1
390
Building Real-time Vue App
joere
4
4.8k
ReactNativeのAsyncStorageをNodeのReplから操作する
joere
0
370
Mock Native API in your E2E test
joere
2
1.3k
Other Decks in Technology
See All in Technology
可視化から始めたAI駆動開発_ochi_ver1.01 / AI-Driven Development Starting with Visualization_ver1.01
yayoi_dd
0
110
形式手法を使って仕様をコーディングしよう
mikanichinose
0
160
検証フェーズはAIの回答を判断するための学習機会
toru_kubota
2
200
ビジネスを止めない技術的負債の返済のための戦略とその手法 - 技術的負債と向き合う / Complexity and Simplicity
soudai
PRO
2
350
PQC移行の今 -- IETF からみた現在地
satokan
4
720
2026-10-01_MagicPod_QAハーネスエンジニアリングとQA組織の未来像
ynisqa1988
0
230
顧客の成果創出とプロダクトの成長を 両立するためのFDE
sansantech
PRO
0
590
『GOエコノミー 』(相乗りサービス) におけるスペック駆動開発
mot_techtalk
1
140
HacobuにおけるFDEとは/登壇資料(戸井田 裕貴)
hacobu
PRO
1
690
個別開発で終わらせない。 現場の課題をプロダクトの強さに変える StockmarkのFDE
ktkrhr
0
520
AI駆動開発で仕様はどこまで書くべきか? ― 人とAIの責務境界から考える開発プロセスの実践
takahiromatsui
1
280
Meet AgentCore Identity Consent Portal
hironobuiga
2
150
Featured
See All Featured
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
Balancing Empowerment & Direction
lara
6
1.3k
Why Our Code Smells
bkeepers
PRO
340
58k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
380
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
SEO for Brand Visibility & Recognition
aleyda
0
4.8k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
290
Transcript
Our choice in ReactNative @joe_re
Who am I? • twitter: @joe_re • github: @joe-re •
working in freee K.K
Released Android app using React Native
Today’s Topics • How was ReactNative? • Using NativeLayer’s assets
• Architecture of JS Layer • For Release
Notice • 今回作ったアプリはAndroid向けなので、 基本的には Androidの話です • JS LayerにはなるべくAndroidでしか動かない コードは書かないようにしていますが、 クロスプラットフォームの話はしません
まずどういうものかDEMO
How was ReactNative?
プロジェクト概要 • 開発期間: 3ヶ⽉月 • 開発メンバー:2名 - Webフロントメインなエンジニア1名 - インターン1名
• モバイルエンジニアは開発メンバーには いない
Q: ReactNativeでは Webフロントの知⾒見見だけで Nativeアプリケーションが 作れるのか
Q: ReactNativeでは Webフロントの知⾒見見だけで Nativeアプリケーションが 作れるのか
やっぱりNativeの知識は必要 • Nativeの資産を⽣生かしたい場⾯面では NativeLayerを書く必要がある • UIコンポーネントもSDKに提供されているも のを使うので、ある程度知識があるとハマり どころは回避しやすい • その他ビルドスクリプトの微調整など
Q: ReactNativeを 採⽤用して効果的だったか
Q: ReactNativeを 採⽤用して効果的だったか
今回の開発体制、 状況的には正解だったと思う • 開発メンバーにモバイルエンジニアがいない中で、 使い慣れたReactでフロントが構築できるのは ⾮非常に効率的だった • 社内にはモバイルエンジニアがいるので、 モバイルについていつでも質問はできる環境があった •
補⾜足として、Javaはチョット書けたし、 モバイルもまぁ書いたことがないわけではなかった
Using NativeLayer’s assets
提供している機能をざっくり • NFCタグを読み取り使⽤用履履歴に変換 • 使⽤用履履歴を元に経費申請する • その他Webとの連携 Native Layer JS
Layer
Android SDKはNFCタグの 操作を提供している https://developer.android.com/reference/android/nfc/package- summary.html
Android SDKの NfcAdapterを利利⽤用するには • Android SDKの提供するAPIを利利⽤用できるよう にするために、NfcAdapterの機能をラップし たNativeModuleを作成する • Reactのライフサイクルに合わせて、
作成したNativeModuleのAPIを呼び出す
Wrap NFCAdapter @ReactMethod QVCMJDWPJETUBSU3FBEJOH/GD \ /GD"EBQUFSOGD"EBQUFS /GD"EBQUFSHFU%FGBVMU"EBQUFS SFBDU$POUFYUHFU"QQMJDBUJPO$POUFYU "DUJWJUZBDUJWJUZSFBDU$POUFYUHFU$VSSFOU"DUJWJUZ
JG OGD"EBQUFSOVMMccBDUJWJUZOVMM \ SFUVSO ^ OGD"EBQUFSFOBCMF3FBEFS.PEF BDUJWJUZ OFX$VTUPN3FBEFS$BMMCBDL SFBDU$POUFYU '-"(@3&"%&3@/'$@' OVMM ^ @ReactMethod public void endReadingNfc() { NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(reactContext.getApplicationContext());; Activity activity = reactContext.getCurrentActivity(); if (nfcAdapter == null || activity == null) { return; } nfcAdapter.disableReaderMode(activity); }
Send to JS Layer class CustomReaderCallback implements ReaderCallback { ReactContext
reactContext; public CustomReaderCallback(ReactContext reactContext) { this.reactContext = reactContext; } @Override public void onTagDiscovered(Tag tag) { try { analizeTag(tag); } catch (IOException e) { Crashlytics.logException(e); } } private void analizeTag(Tag tag) throws IOException { FelicaReader reader = new FelicaReader(tag); //… 解析処理理 … sendEvent(reactContext, “READ_CARD", payload); } private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) { reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit(eventName, params); } }
ReactNative Side import { NativeModules, DeviceEventEmitter } from ‘react-native'; class
ReadingCardPage extends React.Component { // … componentDidMount() { NativeModules.NFCReactModule.startReadingNfc(); DeviceEventEmitter.addListener('READ_CARD', this._handleReadCard); } componentWillUnmount() { DeviceEventEmitter.removeListener('READ_CARD', this._handleReadCard); NativeModules.NFCReactModule.endReadingNfc(); } // … }
これだけで簡単に Android SDKの機能を JSから利利⽤用できる
Architecture of JS Layer
Using Redux • Middleware • redux-thunk • redux-promise-middleware • redux-logger
redux-promise-middlewareを 選択した理理由 • middlewareの層に副作⽤用を押し付けるアプローチはなるべく取ら ない⽅方針(多少個⼈人的な趣向が⼊入ってはいる) • ⾮非同期処理理が⼊入るところで、どうしても時間軸を気にしなくては ならないアクションの発⾏行行だけmiddlewareでどうにかしたかった • ⼤大抵の⾮非同期処理理を伴うアクションは、処理理の開始、成功、失敗
の3種類類さえあれば⼗十分 = これらはPromiseのstatusにそのまま対 応している • redux-promise-middlewareはPromiseの状態に従って、 アクションの発⾏行行を⾃自動化してくれる
redux-promise-middleware // action creator const getPost = id => ({
type: 'GET_POST',\ payload: new Promise(resolve => { setTimeout(() => fetch(`/api/posts/${id}`).then(response => { resolve(response.json()); }), 1000); }) }); // reducer const reducer = (state = {}, action) => { switch (action.type) { case 'GET_POST_PENDING': return { isPending: true }; case 'GET_POST_FULFILLED': return { body: action.payload.body }; default: return state; }; } payloadにpromiseを渡す promiseのstatusの遷移に従い actionが⾃自動でdispatchされる
Nativeアプリケーションと ReduxStateとの相性は良い • ReduxStateに画⾯面上の表示の元となっている箇所を全てを押 し込めることで、画⾯面の再構成がいつでも⾏行行えるようになる • モバイルでは、Webよりもエラー復復旧のために アプリケーションレイヤーで保持しておかなくてはいけない 情報は多い(Navigationのスタックなど) •
画⾯面が狭いので、エラー表示⽅方法や復復旧⽅方法も異異なる (ネットワークエラー発⽣生時には、画⾯面全体をエラーページ にする→再読み込みボタンで成功すれば画⾯面を戻す、など)
Routerには react-native-router-fluxを選択 • Reduxサポートが厚いので選択 • いい感じに使えて特に不不満はなかった • けど内部で使っていたNavigationExperimentalが
[email protected]
からdeplicatedになってしまった •
今なら公式のreact-navigationがおすすめ (個⼈人的に使っている感じでは、違和感もないし、 Reduxも普通に使える)
HOCの活⽤用 • 以下の処理理はHOCで共通化 • ログイン必須ページのログイン要求 • flex-boxだけでは対応の 難しい画⾯面のリサイズ (リストビューの横幅の再計算とか) •
Indicatorの表示 • SnackbarなどのNotification表示 • etc…
Example of HOC // for typed hoc pattern: https://github.com/facebook/flow/issues/2521 type
FunctionComponent<P, S> = (props: P, context: S) => ?React$Element<any>; type ClassComponent<D, P, S> = Class<React$Component<D, P, S>>; type Props = { snackbarMessage: SnackbarMessage, actions: typeof Actions }; export default function ShowSnackbar<D, P, S>( WrappedComponent: ClassComponent<D, P, S>|FunctionComponent<P, S> ): ClassComponent<void, P & Props, {}> { return class _ShowSnackbar extends Component { props: P & Props; state: {}; componentWillReceiveProps(nextProps: Props) { if (this.props.snackbarMessage !== nextProps.snackbarMessage) { this.showSnackbar(nextProps.snackbarMessage); } } showSnackbar(snackbarMessage: SnackbarMessage) { // 表示処理理 } render() { return ( <WrappedComponent {...this.props} /> ); } };
For Release
Crash reporting • 社内で実績があったCrashlyticsを導⼊入 • ReactNativeでも導⼊入は簡単 (ReactNative向けにreact-native-fabricという npmが提供されている) • モバイルはユーザ環境によって
予想外のエラーが起きることが多いので、 できればリリース前に⼊入れておくのが良い
不不要な権限は削ろう(Android) • 初期状態では以下の権限が要求される - USBストレージの読み取り - 端末情報とIDの読み取り - 他のアプリの上に重ねて表示 •
USBストレージの読み取りはAsyncStorageを使うために必要だ けど、他の権限は今回のアプリでは不不要 • これらの権限は実はデバッグツールのために要求されているので、 不不要であればリリースバージョンで取り除くようにmanifestを 書くのが良い
app/src/release/ AndroidManifest.xml • Androidのgradleスクリプトでは ディレクトリの規約によりリリース時の Manifestを選択できる <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="jp.co.freee.nfc">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" tools:node="remove" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" /> </manifest>
Yarnを利利⽤用してLicense表記の 雛形を作る • yarnにはlicensesコマンドがあり、package.jsonの依存定義 からLicense表記を⽣生成するコマンドがある • ReactNativeでは基本的にnpmでpackage管理理をするため、 このコマンドをLisense表記の雛形を作るために使うと便便利利 • ライセンス表記は⼊入れなきゃいけないもの、⼊入れなくても
良いものの判断は別途しないといけないので、あくまで雛 形として使いましょう (会社に法務がいる場合は相談しよう)
AsyncStorageREPL (おまけ)
Access AsyncStorage from Node REPL • 開発中気軽にAsyncStorageの中身を⾒見見たり、 変更更したりできないのが不不満だった • NodeのREPLからアプリケーションの
AyncStorageにアクセスしたかった (rails consoleみたいなイメージ)
作った • https://github.com/joe-re/async-storage-repl
DEMO
興味があれば ぜひ使ってみてください
GraphQLのmeetupやります! https://www.meetup.com/ja-JP/GraphQL-Tokyo/events/239924595/ 5/30(⽕火) 20:00〜22:00
React Native is fun
Thank you for your attention!