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
"何を作るか"を任される エンジニアは、どう育つのか
yutaokafuji
1
500
Sync と Async ─ useSyncExternalStore を使う者の岐路
kakehashi
PRO
1
110
2026 TECHFRESH 畢業分享會 - AI-Native 重塑軟體工程與虛擬講師
line_developers_tw
PRO
0
430
MIERUNE JCT 発表資料「宇宙から伊能忠敬ごっこ」
syuchimu
0
200
Bucharest Tech Week 2026 - Reinventing testing practices in the AI era
edeandrea
PRO
0
120
チームで実践する AI-DLC 思考の軌跡を残すチェックポイント設計
belongadmin
0
3.2k
Ruby::Boxでできること、Refinementsでできること
joker1007
3
410
2026 TECHFRESH 畢業分享會 - 開發日常大解密!從領域驅動到企業級上線
line_developers_tw
PRO
0
420
[モダンアプリ勉強会]今更聞けないGit/GitHub入門
tsukuboshi
0
330
Microsoft Build Keynoteふりかえり
tomokusaba
0
120
運用を見据えたAIエージェント設計実践
amacbee
1
3.5k
protovalidate-es を導入してみた
bengo4com
0
160
Featured
See All Featured
Between Models and Reality
mayunak
4
330
Done Done
chrislema
186
16k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.3k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
480
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.5k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.5k
Tell your own story through comics
letsgokoyo
1
950
Leo the Paperboy
mayatellez
7
1.8k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
840
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.5k
The browser strikes back
jonoalderson
0
1.2k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
1
170
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!