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
SQL Server 2025 最適化されたロック
odashinsuke
0
120
人にやさしく、AIにやさしく、書き手を選ばないIaCのガードレール再考 / Rethinking IaC Guardrails for Humans and AI Alike
kohbis
5
2k
セルフサービスのオブザーバビリティ基盤をOpenTelemetryで作る / Building a Self-Service Observability Platform with OpenTelemetry
ymotongpoo
3
500
『GOエコノミー 』(相乗りサービス) におけるスペック駆動開発
mot_techtalk
1
150
Claude Designがめちゃくちゃ便利なので使ってほしい
diggymo
0
190
AI臭い文章とは何なのか
nasuvitz
38
76k
【Findyテック文化祭ワークショップ】新卒エンジニア&採用担当と作る、 なりたい姿と今やるべき一歩
dip_tech
PRO
0
150
20260929_AmazonGuardDutyの検出通知メールにAWS DevOpsAgentの調査結果を追加する
yhana
1
410
生成AIを使って「人が」考える技術 ― AI時代の人機共想と実践ノウハウ|UNITT AC2026
ishiirikie
0
510
BedrockとLambdaで作る リアルタイム進行型推理ゲーム
kawametho
0
150
Execution in the Kingdom of Agents: Reflections on Abstraction and Complexity
bcantrill
0
640
OSC2026on_the-world-is-waiting-for-your-voice.pdf
naruoga
0
180
Featured
See All Featured
Optimizing for Happiness
mojombo
378
71k
WCS-LA-2024
lcolladotor
0
840
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Ruling the World: When Life Gets Gamed
codingconduct
0
380
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
Embracing the Ebb and Flow
colly
88
5.2k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
490
A Modern Web Designer's Workflow
chriscoyier
699
190k
The browser strikes back
jonoalderson
0
1.7k
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!