Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
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
120
Building Public API with GraphQL
joere
3
140
Traversing the GraphQL AST and Calculating Query Costs
joere
0
1.3k
Real-Time applications with GraphQL
joere
0
300
Prisma2 with Graphql
joere
3
1k
Go beyound static on Netlify
joere
1
370
Building Real-time Vue App
joere
4
4.7k
ReactNativeのAsyncStorageをNodeのReplから操作する
joere
0
350
Mock Native API in your E2E test
joere
2
1.2k
Other Decks in Technology
See All in Technology
AIっぽい文章を採点して人間らしく直すアプリを作ってみた
yama3133
2
120
中期計画、2回作ってみた ~業務委託と正社員、両方の視点から~
demaecan
1
660
Oracle AI Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
4
2.9k
On-behalf-of Token exchange with AgentCore Identity
hironobuiga
2
140
LLMにもCAP定理があるという話
harukasakihara
0
280
小さく始める AI 活用推進 ― 日経電子版 Web チームの事例/nikkei-tech-talk47
nikkei_engineer_recruiting
0
200
Disciplined Vibes: Scaling AI-Assisted Engineering
sheharyar
0
130
2026TECHFRESH畢業分享會 - 原生還是跨平台? App 開發踩坑實錄
line_developers_tw
PRO
0
740
AI駆動開発が変える、大規模開発の前提 ーHuman in the Loop から Human on the Loop へ / AIE2026
visional_engineering_and_design
30
24k
SIer20年! 培ったスキルがスタートアップで輝く時
shucho0103
0
830
機械学習を「社会実装」するということ 2026年夏版 / Social Implementation of Machine Learning June 2026 Version
moepy_stats
4
1.3k
日本 Fintech 未来予測レポート 2027〜2028年(手動編集版)
8maki
0
1.5k
Featured
See All Featured
The untapped power of vector embeddings
frankvandijk
2
1.8k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.3k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.3k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
230
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
160
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
Marketing to machines
jonoalderson
1
5.4k
The browser strikes back
jonoalderson
0
1.2k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
570
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
480
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
Building an army of robots
kneath
306
46k
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!