12th of December 2017 @HumanTalksParis
Aurore Malherbes Mobile Engineer @AuroreMa27 @bam_lab
"I'm a JS dev, can I code a mobile app?"
"Can I use the lastest feature of iOS 11 in my React Native app?"
"It's owned by Facebook, I think it's an issue."
"But the app performance are not good, are they?"
"How long does it take to code an app with geolocation in React Native?"
@AuroreMa27
"Never heard of it. Is it like ionic?"
Many years ago ...
@AuroreMa27
2013
Internal Hackathon at Facebook
TODAY
- 1653 contributors
- Used in famous apps
2015
F8 conference, first public release
2012 "I think the biggest mistake that we made, as a company, is betting too much on HTML5 as opposed to native"
@AuroreMa27
What I love about React Native
@AuroreMa27
SO ...
@AuroreMa27
...IT SAVES TIME 🕐
Hot reloading
CodePush
@AuroreMa27
69.8%
45.3%
8.1%
JS
JAVA
SWIFT
... HIRING SHOULD BE EASIER 👩💻
... CHANGING AS WELL 👨🏻💻
@AuroreMa27
What's annoying me with React Native
@AuroreMa27
MONTHLY UPDATE 🗓
@AuroreMa27
@AuroreMa27
A MOVING ECOSYSTEM 🎢
react-native-router-flux
react-navigation
flow
typescript
redux
context
...
...
@AuroreMa27
MISSING NATIVE FEATURES 🕵️♀️ ...
@AuroreMa27
... BUT THERE IS ALWAYS A LIB 👨🏻🔧
https://github.com/react-native-ar/react-native-arkit.git
https://github.com/jordanbyron/react-native-quick-actions.git
@AuroreMa27
AND IN TERMS OF ANIMATIONS? 🦄
@AuroreMa27
AND IN TERMS OF ANIMATIONS? 🦄
Easy
Moderate
Difficult
An element appears in fade-in
Animated, react-native-animated
Keep an element from one page to another and get an animated transition
FluidTransition
An element follows the user's finger
react-native-interactable
@AuroreMa27
Let's code !
@AuroreMa27
github.com/AuroreM/verona-live
react-native-maps
react-native-camera
react-navigation
@AuroreMa27
Geolocated INSTAGRAM
$ npm install -g create-react-native-app
$ create-react-native-app verona-live
GETTING STARTED 🏁
App.js
App.test.js
README.md
node_modules/
package.json
yarn.lock
@AuroreMa27
$ npm install -g create-react-native-app
$ create-react-native-app verona-live
GETTING STARTED 🏁
$ yarn eject
android/
index.js
ios/
App.js
// index.js
import { AppRegistry } from 'react-native';
import App from 'veronalive/src/App';
AppRegistry.registerComponent('veronalive', () => App);
@AuroreMa27
$ npm install -g create-react-native-app
$ create-react-native-app verona-live
GETTING STARTED 🏁
$ npm install -g yo generator-rn-toolbox
$ yo rn-toolbox:base
$ yarn run ios
https://github.com/bamlab/generator-rn-toolbox
$ yarn eject
src/
components/
modules/
pages/
App.js
RootNavigation.js
@AuroreMa27
BE READY TO ... DEBUG 🐞
$ brew update && brew cask install react-native-debugger
@AuroreMa27
REACT's LITTLE BROTHER 👨👦
import React, { Component } from 'react';
export default class Home extends Component {
render() {
return <Page />;
}
}
@AuroreMa27
REACT's LITTLE BROTHER 👨👦
// REACTJS
<Page>
<div>
<p>Welcome to JSDay!</p>
<button onPress={this.onPress}>
<p>Click here!</p>
</button>
</div>
</Page>
@AuroreMa27
// REACT NATIVE
<Page>
<View>
<Text>Welcome to JSDay!</Text>
<TouchableOpacity onPress={this.onPress}>
<Text>Click here!</Text>
</TouchableOpacity>
</View>
</Page>
REACT's LITTLE BROTHER 👨👦
@AuroreMa27
// REACTJS
import styled from 'styled-components';
export Container = styled.div`
display: flex;
flex-direction: 'column';
justify-content: 'flex-end';
padding: 20px;
`;
<Container></Container>
// REACT NATIVE
import { StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
padding: 20,
justifyContent: 'space-around',
}
});
<View style={styles.container}></View>
LET's NAVIGATE 🚂
@AuroreMa27
LET's NAVIGATE 🚂
@AuroreMa27
import { StackNavigator } from 'react-navigation';
// Define your stack(s)
export const AppNavigator = StackNavigator(
{
home: {
screen: Pages.Home,
},
list: {
screen: Pages.List,
},
},
{
initialRouteName: 'home',
headerMode: 'none',
}
);
LET's NAVIGATE 🚂
// Home.component.js
export default class Home extends Component {
onPress = () =>
this.props.navigation.navigate('list');
render() {
return (
<TouchableOpacity onPress={this.onPress}>
<Text>Go to the list page 🚀</Text>
</TouchableOpacity>
);
}
}
@AuroreMa27
// List.component.js
export default class List extends Component {
onPress = () =>
this.props.navigation.goBack();
render() {
return (
<TouchableOpacity onPress={this.onPress}>
<Text>Go back to the homepage 🏔</Text>
</TouchableOpacity>
);
}
}
@AuroreMa27
WHERE AM I? 🗺
$ yarn add react-native-maps
$ yarn add react-native-permissions
@AuroreMa27
// AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
// Info.plist
<key>NSLocationWhenInUseUsageDescription</key>
<string>The app requires access to your location</string>
WHERE AM I? 🗺
@AuroreMa27
$ react-native link react-native-maps
$ react-native link react-native-permissions
WHERE AM I? 🗺
import { MapView } from 'react-native-maps';
<MapView
initialRegion={{
latitude: this.state.latitude,
longitude: this.state.longitude,
latitudeDelta: 0.09,
longitudeDelta: 0.05,
}}
showsUserLocation
/>
@AuroreMa27
WHERE AM I? 🗺
// geolocation.js
export const getCurrentLocation = () => {
return checkLocationPermission().then(() => {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
position => resolve(position),
e => reject(e)
);
});
});
};
@AuroreMa27
WHERE AM I? 🗺
// geolocation.js
const checkLocationPermission = () => {
return Permissions.check('location').then(status => {
switch (status) {
case 'authorized':
return true;
case 'undetermined':
Permissions.request('location')
.then(response => response === 'authorized');
case 'restricted':
case 'denied':
default:
return false;
}
});
};
@AuroreMa27
@AuroreMa27
CHEESE 📸
$ yarn add react-native-camera
$ react-native link react-native-camera
@AuroreMa27
CHEESE 📸
import { RNCamera } from 'react-native-camera';
export default class Camera extends Component {
takePicture = async function() {};
render() {
return (
<View>
<RNCamera
ref={ref => this.camera = ref}
type={RNCamera.Constants.Type.back}
flashMode={RNCamera.Constants.FlashMode.on}
permissionDialogTitle={'Permission to use camera'}
permissionDialogMessage={'We need your permission to use your camera'}
/>
<TouchableOpacity onPress={this.takePicture.bind(this))}>
<Text>Take a picture 🕶</Text>
</TouchableOpacity>
</View>
);
}
}
@AuroreMa27
CHEESE 📸
takePicture = async function() {
if (this.camera) {
const data = await this.camera.takePictureAsync(
{ quality: 0.5, base64: true }
);
this.props.storePicture(data.uri);
this.props.navigation.goBack();
}
};
@AuroreMa27
@AuroreMa27
What I love about React Native (2nd round)
@AuroreMa27
...EVERYONE CAN USE YOUR APP 🌎
@AuroreMa27
...EVERYONE CAN USE YOUR APP 🌎
/Microsoft/react-native-windows
/necolas/react-native-web
@AuroreMa27
...AND THERE IS NO REAL PERFORMANCE GAP... 🚴🏻♀️
@AuroreMa27
...EXCEPT FOR COMPLEX ANIMATIONS... 🚴🏻♀️
@AuroreMa27
"Performance limitations of react-native and how to overcome them" from @talkoh on Medium
...SOMETIMES IT IS EVEN FASTER... 🚴🏻♀️
@AuroreMa27
@AuroreMa27
EXCEPT :
- Your business relies on new features of iOS and Android
- Your business relies on far-fetched animations
- You hate Javascript
@AuroreMa27