React Native on the Web
Twitter Lite
React Native
... on the Web 🤔
HTML
HTML is too Difficult
Difficult => Complex
Complexity Factor
- UIに意味をもたせる難しさ
- 状態とUI
- レスポンシブなデザイン
- セマンティックなHTMLとは
- <div>, <section>, <article>, ...
- <strong>, <b>, <em>, <i>, ...
Native App UI meets Web
WebとNative Appの境目はなくなりつつある
Components from Native App to Web
- Pull to Refresh
- Highlight on Tap
- Gesture (Swipe, Long Press, Force Touch)
- Offline
- and other UIs ...
対応するためのTips
- flexbox, grid layout
- reset.css
- aタグよりbuttonタグ
- :active :hoverの考え方
- -webkit-overflow-scrolling
解決のためのライブラリ
- Onsen UI
- Ionic
- Ratchet
- Semantic-ui
- jQuery mobile
React Native
React Native
- JavaScriptでiOS, Android アプリを作れる
- JSはブリッジで各ネイティブコンポーネントを呼び出す
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Button
onPress={onPressLearnMore}
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Button
onPress={onPressLearnMore}
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});
<View>はレイアウトに関することのみ
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Button
onPress={onPressLearnMore}
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});
<Text>はテキストに関することのみ
代表的なコンポーネント
<View>
<Text>
<TextInput>
<Button>
<Image>
<Picker>
<Slider>
<Switch>
<WebView>
<ScrollView>
<ListView>
代表的なコンポーネント
<View>
<Text>
<TextInput>
<Button>
<Image>
<Picker>
<Slider>
<Switch>
<WebView>
<ScrollView>
<ListView>
<div>, <section>, <artcle>
<span>, <h1>, <h2>,<p>
<input>, <textarea>
<a>, <button>
<img>
<select>, <option>
render() {
return (
<ListView
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh.bind(this)}
/>
}
...
>
...
</ListView>
);
}
Pull to Refresh
render() {
return (
<View>
<TouchableOpacity
style={styles.button}
onPress={this.onPress}
>
<Text> Touch Here </Text>
</TouchableOpacity>
<TouchableHighlight
style={styles.button}
onPress={this.onPressImage}
>
<Image source={{url:...}} />
</TouchableHighlight>
</View>
)
}
feedback on Touch
render() {
return (
<View>
<ActivityIndicator size="large" color="#0000ff" />
</View>
)
}
ActivityIndicator
render() {
return (
<View>
<Text
numberOfLines={2}
> Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's
standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five ce
nturies, but also the leap into electronic typesetting, remaining essentially unchanged.
</Text>
</View>
)
}
numberOfLines
render() {
return (
<View>
<View style={{ marginBottom: 100 }}>
<Text>margin bottom 100</Text>
</View>
<View style={{ marginTop: 100 }}>
<Text>margin top 100</Text>
</View>
</View>
)
}
no margin conflict
React Native のコンポーネント
- UIコンポーネントを抽象化
- 必要な(低レベルな)UIコンポーネントが揃っている
- コンポーネントの責務が明確化
- テキストを扱うためにspan, p,などタグに迷わない
- 考えることが減って実装がシンプルに
React Native Web
React Native for Web
React Native for Web
React DOMでReact NativeコンポーネントやAPIを実行することができる。ベースはReact.js
-
できること
- 簡単で高速にWeb UIを作成
- ネイティブのインタラクション
- タッチ・マウス・キーボード入力サポート
- ベンダプレフィックスサポート
- RTLレイアウト、アクセシビリティ
- React Dev Tool
- Write once, render anywhere
- 書いたコードはReact Nativeでも大半は利用可能
- Node.jsを用いてSSRも可能
React Native for Web
実績
- Twitter Lite - https://mobile.twitter.com/
- Major League Soccer - https://matchcenter.mlssoccer.com/
- Flipkart - https://www.flipkart.com/
- Playstation
- Uber
- The Times - http://components.thetimes.co.uk
React Native Dom
React Native Dom
React NativeのコードをWebに展開。ベースはReact Native
- モバイル上のReact Nativeと同じアーキテクチャを利用
- ReactコンポーネントのロジックはWeb Workerで実行されメインスレットはレンダリングのみ行う
- React Native on mobileと同じレイアウト
- YogaへのカスタムバインディングとWebアセンブリにコンパイルを利用することにより、ネイティブとウェブで同じレイアウトを実現
- Metro Bundlerを利用
- DOM APIにも対応
- こっちこそWrite once, render anywhere
React Native Dom
ただしまだExperimental😜
まとめ
- 低レイヤーコンポーネントの責務の明確化
- React Nativeのコンポーネントは簡単でシンプルな新たなhtmlといえる
- React Nativeのコンポーネントは簡単でシンプルな新たなhtmlといえる
-
Write once, render anywhereの実現
- Web/iOS/Androidが混在するプロジェクトが多い昨今、React Native Webは選択肢としてありなのでは?
END
deck
By Kyohei Rampage Tsukuda
deck
- 785