React Native
2017.3.9 DroidKaigi 2017
Yukiya Nakagawa / @Nkzn
ROOM 3 17:10-17:40
#droidkaigi3
Who are you?
• Yukiya Nakagawa / @Nkzn
• @
•
•
• Android 2009
React Native
•
• Hello World
• Production
Target
• Android / iOS
• React React Native
• React Native
Agenda
•
‣
‣ React
‣ React Native
•
‣ React Native
‣
‣
• React
• React Native
• React Native Before / After
• React (DOM)
• ES201x
• NPM
• React Native
Biz
Biz
• Android iOS
•
•
•
https://www.kantarworldpanel.com/global/smartphone-os-market-share/
•
•
• iOS Android
1
Android iOS
OS
UI
WebView Cordova Xamarin Unity
React
React
https://facebook.github.io/react/
•
• JSX
•
Reactive
JSX
<div>
<Header />
<LeftPane />
<RightPane />
</div>
React
import React from 'react';
import ReactDOM from 'react-dom';
const styles = {
container: {display: 'flex', flexDirection: ‘row', …}
};
class App extends React.Component {
render() {
const myName = /* props or state */;
return (
<div style={styles.container}>
<Header />
<LeftPane />
<RightPane
name={myName} />
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
Virtual DOM
React DOM
React DOM
React DOM
React DOM
https://tylermcginnis.com/an-introduction-to-life-cycle-events-in-react-js/
https://developer.android.com/reference/android/app/Activity.html
React is
• Facebook JS
• https://facebook.github.io/react/
•
•
• View
View View
React Native
(Side React)
Android View
Android
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<include layout="@layout/header" />
<include layout="@layout/left_pane" />
<include layout="@layout/right_pane" />
</RelativeLayout>
Android View
<include layout=
“@layout/header”/>
android.view.View
<include layout=
“@layout/left_pane”/>
<include layout=
“@layout/right_pane”/>
• Fragment
•
• Advocating Against Android Fragments
• https://medium.com/square-corner-blog/advocating-against-
android-fragments-81fd0b462c97
• ( ) http://ninjinkun.hatenablog.com/entry/
2014/10/16/234611
Android View
View
DOM
Android View
View
DOM
React is
• Facebook JS
• https://facebook.github.io/react/
•
•
• View
View View
React
DOM
import React from 'react';
import ReactDOM from 'react-dom';
const styles = {
container: {display: 'flex', flexDirection: ‘row', …}
};
class App extends React.Component {
render() {
const myName = /* props or state */;
return (
<div style={styles.container}>
<Header />
<LeftPane />
<RightPane
name={myName} />
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
import ReactDOM from 'react-dom';
div
div
ReactDOM.render(
<App />,
document.getElementById('app')
);
import React from "react";
import { View, AppRegistry } from "react-native";
const styles = {
container: {display: 'flex', flexDirection: ‘row', …}
};
class App extends React.Component {
render() {
const myName = /* props or state */;
return (
<View style={styles.container}>
<Header />
<LeftPane />
<RightPane
name={myName} />
</View>
);
}
}
AppRegistry.registerComponent(
"App",
() => App
);
React
ReactDOM
React
UI
React Native
React Native
(Side Android)
Android iOS
OS
UI
React Native
Android iOS
OS
UI
React Native Android
(Side UI Component)
ReactRootView
• FrameLayout
• onMeasure JavaScriptCore
JS JS
ReactRootView RootView
(ReactActivityDelegate.java)
protected ReactRootView createRootView() {
return new ReactRootView(getContext());
}
//
protected void onCreate(Bundle savedInstanceState) {
//
if (mMainComponentName != null && !needsOverlayPermission) {
loadApp(mMainComponentName);
}
//
}
protected void loadApp(String appKey) {
if (mReactRootView != null) {
throw new IllegalStateException("Cannot loadApp while app is already running.");
}
mReactRootView = createRootView();
mReactRootView.startReactApplication(
getReactNativeHost().getReactInstanceManager(),
appKey,
getLaunchOptions());
getPlainActivity().setContentView(mReactRootView);
}
https://github.com/facebook/react-native/blob/d21aa9248056b08449f4a0f57e824b3c52b0614b/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java#L67-L115
Activity ReactRootView JS
View
View
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions1}>
To get started, edit index.android.js
</Text>
<Text style={styles.instructions2}>
Shake or press menu button for dev menu
</Text>
</View>
react.gradle
JS
: import
JS
$buildDir/intermediates/
assets/index.android.bundle
JS
React Native Android
(Side Native Module)
JS
UI
(Web API)
https://developer.mozilla.org/ja/docs/Web/Reference/API
/Libraries/Core/Timers/JSTimers.js
/ReactAndroid/src/main/java/com/facebook/react/modules/core/Timing.java
(※ )
Polyfill
https://facebook.github.io/react-native/docs/javascript-environment.html
• React View
• API
JS
• UI ReactRootView
UI
React Native
Android iOS
OS
UI
http://facebook.github.io/react-native/showcase.html
https://design.google.com/articles/airbnb/
React Native
Biz
• Android iOS
•
•
•
Facebook
JA
• iOS Cordova + React
Web
• 1 iOS/Android
• React
•
React Native
UI
CSS
• CSS
const styles = StyleSheet.create({
container: {
paddingTop: metrics.x4,
paddingBottom: metrics.x2
},
logo: {
height: 180,
alignSelf: "center"
},
loginBox: {
marginTop: metrics.x4,
marginHorizontal: metrics.x4
}
});
<View
style={styles.container}>
…
</View>
CSS
• CSS
• CSS
• Bootstrap Material Design Lite
• CSS React
• OnsenUI material-ui
Android, iOS
Material Design
const metrics = {
x0_25: 2,
x0_5: 4,
x0_75: 6,
x1: 8,
x1_5: 12,
x2: 16,
x2_5: 20,
x3: 24,
x4: 32,
x5: 40,
x6: 48,
x7: 56,
x8: 64,
x9: 72
};
export default metrics;
metrics.android.js
const metrics = {
x0_25: 2,
x0_5: 4,
x0_75: 6,
x1: 8,
x1_5: 11,
x2: 15,
x2_5: 20,
x3: 22,
x4: 32,
x5: 40,
x6: 44,
x7: 56,
x8: 64,
x9: 72
};
export default metrics;
metrics.ios.js
• <Image>
•
• Android Picasso PhotoView
• iOS UIScrollView
JS
http://square.github.io/picasso/
https://github.com/chrisbanes/PhotoView
React Native
HelloWorld
JS
• API
• lodash
• API
React Native
•
• API
orz
• VSCode JS
• Android/iOS
Android iOS
• JS R Live
Reload
• Android Studio Xcode
VSCode
Android
Studio
Xcode
Android
iOS
Live Reload
• JS
localhost
•
• Initial commit: 2 22
• v1.0.0 : 5 11
2
CI
•
• Android Java, Android SDK
• iOS OS X, Xcode, iOS SDK
• Fastlane CocoaPods Ruby
• mac mini
React Native
+ React
• Web View
React
• Learn Once, Write Anywhere
• React Native
•
React Native
• Breaking Change
Breaking Change
• React Native
•
React Native
• Breaking Change
•
•
• v2
2
React Native
React Native
React Native
• WebView React
• UI Native
Component/Module
• Android Java,
React Native
React
Android
!
React Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigi

React Nativeはクロスプラットフォームモバイルアプリ開発の夢を見るか #DroidKaigi