Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Developing React Native Upon Native App (React Native Portland meetup)

Developing React Native Upon Native App (React Native Portland meetup)

A talk about how we developed React Native upon Native app, especially from Android stand point.
There are 3 topics:
1. how our architecture looks like and key components to make a hybrid app work
2. Developing and Testing flow
3. How the team changed by developing a hybrid app

Tomoaki Imai

July 20, 2017
Tweet

More Decks by Tomoaki Imai

Other Decks in Programming

Transcript

  1. Hi I’m Tomo Mobile Developer (Android, ReactNative, iOS) Joined Mercari,

    Inc. 2014 twitter: @tomoaki_imai github: tomoima525
  2. Native + React Native Hybrid App /BUJWFTDSFFOT 3FBDU/BUJWFTDSFFOT 5JNF-JOF -JTUJOH

    $BNFSB (BMMFSZ $IFDLPVU *UFN%FUBJM %FFQMJOL8FC 4FUUJOHT &EJU  1SPpMF *OCPY $IBU 'PMMPXMJTU )BTBOJNBUJPO .VMUJUISFBEFEQSPDFTT 6TFT04'SBNFXPSL 4UBUJDQBHFT .PSFGBODZTDSFFOT
  3. Developing Hybrid App is not simple! - How to Bridge

    data between React Native & Native - Using Native thru React Native, vice versa - Developing/Testing React Native upon Native App • Need to consider more things compared to React Native App
  4. Agenda - Hybrid App Architecture and Key Components - Developing/Testing

    Flow for Hybrid App - How the team changed by developing Hybrid App
  5. 3FBDU'SBHNFOU 3FBDU3PPU7JFX Architecture in a nutshell 3FBDU/BUJWF 3FBDU*OTUBODF.BOBHFS /BUJWF .PEVMFT

    0UIFS "DUJWJUJFT 3FBDU 4FSWJDF &WFOU )PPL 3FBDU 3FQPTJUPSZ JS bundle file React Native Native Framework Bridge
  6. 3FBDU'SBHNFOU 3FBDU3PPU7JFX Architecture in a nutshell 3FBDU/BUJWF 3FBDU*OTUBODF.BOBHFS /BUJWF .PEVMFT

    0UIFS "DUJWJUJFT 3FBDU 4FSWJDF &WFOU )PPL 3FBDU 3FQPTJUPSZ JS bundle file React Native Native Framework Bridge
  7. React Service & React Repository • React Service is a

    factory class that creates React Instance Manager • Also checks updates on JS Bundle • React Repository is where JS Bundle file is stored 3FBDU 4FSWJDF 3FBDU 3FQPTJUPSZ Load Bundle on memory from Asset directory 3FBDU*OTUBODF .BOBHFS Checks update on server Bundle from Local server (for development usage)
  8. 3FBDU'SBHNFOU 3FBDU3PPU7JFX Architecture in a nutshell 3FBDU/BUJWF 3FBDU*OTUBODF.BOBHFS /BUJWF .PEVMFT

    0UIFS "DUJWJUJFT 3FBDU 4FSWJDF &WFOU )PPL 3FBDU 3FQPTJUPSZ JS bundle file React Native Native Framework Bridge
  9. React Fragment scene = “INBOX” USER_ID = “xxxx” HashMap<String, String>

    data = new HashMap<>(1);
 data.put(USER_ID, userId);
 ReactFragment inboxContent = ReactFragment.newInstance(INBOX, data); • Handles which React Native Screen to open HomeActivity.java
  10. React Fragment scene = “INBOX” USER_ID = “xxxx” HashMap<String, String>

    data = new HashMap<>(1);
 data.put(USER_ID, userId);
 ReactFragment inboxContent = ReactFragment.newInstance(INBOX, data); HashMap<String, String> params = getArguments().getSerializable(DATA); 
 Bundle bundle = new Bundle();
 bundle.putString( ”initialScene”, getArguments().getSerializable(SCENE));
 bundle.putSerializable(React.Param.DATA, data); 
 reactView.startReactApplication( reactManager, ReactService.MAIN_MODULE, bundle); • Handles which React Native Screen to open HomeActivity.java ReactFragment.java
  11. React Fragment • Handles which React Native Screen to open

    class InboxScene extends React.Component { getChildContext() { if (this.props.user_id) { return { data: { user_id: this.props.user_id } }; } } … import * as scenes from './scenes'; const RouterWithRedux = connect()(Router); const initialSceneProps = { initial: true }; const Scenes = (props, context) => <RouterWithRedux navigationBarStyle={styles.navigationBarStyle}> <Scene key="root"> { // Setup all scenes _.map(scenes, (component, name) => ( <Scene key={name} title={name} component={component} // Setup initial scene {...(context.initialScene === name ? initialSceneProps : {})}/>))} </Scene> </RouterWithRedux>;
  12. 3FBDU'SBHNFOU 3FBDU3PPU7JFX Architecture in a nutshell 3FBDU/BUJWF 3FBDU*OTUBODF.BOBHFS /BUJWF .PEVMFT

    0UIFS "DUJWJUJFT 3FBDU 4FSWJDF &WFOU )PPL 3FBDU 3FQPTJUPSZ JS bundle file React Native Native Framework Bridge
  13. Event Hook Module • Native Module that pass events/data from

    React Native to Native import { NativeModules } from 'react-native'; export const openActivity = (name, data = null) => { NativeModules.EventHook.sendEvent('openActivity', { name,data}); };
  14. class ReactEventHookModule extends ReactContextBaseJavaModule {
 ReactEventHooks hooks;
 @ReactMethod
 public void

    sendEvent(String name, @Nullable ReadableMap data) {
 // receive parameters from react module
 hooks.getEventProcessor().onNext(new ReactEvent(name, data));
 }
 } Event Hook Module • Native Module that pass events/data from React Native to Native import { NativeModules } from 'react-native'; export const openActivity = (name, data = null) => { NativeModules.EventHook.sendEvent('openActivity', { name,data}); }; // ReactFragment.java public boolean handleEvent(ReactEvent reactEvent) {
 switch (reactEvent.getName()) {
 case ”openActivity”:
 openActivity(reactEvent);
 break;
 ….
  15. Testing from device • Download JS Bundle file from GCS

    • JS Bundle can be selected with Pull Request # on Github • Super easy to test with an actual device!
  16. Code faster, Deploy faster! • All engineer can contribute to

    mobile app • Over The Air update every week When All tasks are Native Native + React Native Frontend Engineer Server Engineer 2 Native Engineers
  17. React Native experience for Android Developer Hard to find error

    in JSX (it won’t show in Debugger) No Type or Null check (started to introduce Flow) Clean Architecture. Thanks to Redux and Atomic design! Less code with ES6 Live reloading!!