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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
130
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
380
Building Real-time Vue App
joere
4
4.7k
ReactNativeのAsyncStorageをNodeのReplから操作する
joere
0
360
Mock Native API in your E2E test
joere
2
1.2k
Other Decks in Technology
See All in Technology
水を運ぶ人としてのリーダーシップ
izumii19
4
1k
WebGIS AI Agentの紹介
_shimizu
0
580
AIをフル活用してオンコール機能のプロトタイプを2日で作った話 / Building an AI-Powered On-Call Prototype in Just Two Days
nari_ex
0
140
初めてのDatabricks勉強会
taka_aki
2
170
はてなのサービス基盤を支える Kubernetes《足腰》
masayoshimaezawa
0
130
[AWS Summit Japan 2026]迷っているあなたへ_小さな一歩が、やがて自分を助けてくれる
sh_fk2
2
420
起点・思考・出力で分解する 〜PM業務の自動化設計〜
kazu_kichi_67
2
1.1k
不要なレビューをAIにまかせて AIコーディングの環境改善を加速した
shoota
1
270
When Platform Engineering Meets GenAI
sucitw
0
200
從觀望到全公司落地:AI Agentic Coding 導入實戰 — 流程整合與安全治理
appleboy
0
110
Lightning近況報告
kozy4324
0
220
時期が悪い!それでもRaspberry Piを買って遊んで活用するには / 20260627-osc26do-rpi-jikigawarui
akkiesoft
1
870
Featured
See All Featured
First, design no harm
axbom
PRO
2
1.2k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
870
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
580
Accessibility Awareness
sabderemane
1
140
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.3k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
72
40k
Scaling GitHub
holman
464
140k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
340
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.6k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
610
How to make the Groovebox
asonas
2
2.2k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
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!