SlideShare a Scribd company logo
Crossing platforms with
JavaScript & React
@robdel12
JavaScript is
EVERYWHERE
Web
Server
iOS
Android
Desktop
Crossing platforms with JavaScript & React
What is cross platform
JS?
JS that can run on
more than one platform
Crossing platforms with JavaScript & React
“Why did the iOS team implement it
like this?”
“The Android app currently doesn’t
support that”
https://twitter.com/dan_abramov/status/812047645732651009
Easier to share code across many
teams
More team collaboration since there’s
more overlap
It allows teams to own products & not
be separated by technology
TL;DR your team now owns the iOS,
Android, and (maybe) web apps.
Consistency is 🔑
Cheaper
If you can build iOS & Android apps in the
same code base it should be cheaper
Why not bet on the web?
Native will be better than mobile web
for a while
Why not take the web tooling & get
native results?
You are betting on the web
Can’t beat them, join them
I decided to be ambitious
Build an Instagram clone for Web, iOS,
& Android
Why an Instagram clone?
Use Impagination.js to power an
Infinite scroll of images
Crossing platforms with JavaScript & React
Impagination will work on any JS
codebase
Building infinite scroll in React Native
with Impagination
http://bit.ly/reactnativeinfinitescroll
We’ve already used Impagination in
four different platforms
What else can be shared?
Experiment time
Crossing platforms with JavaScript & React
Three phases to the
experiment
• Planning
• Implementation
• Postmortem
Planning
Crossing platforms with JavaScript & React
🥞The stack🥞
• React Native
• React (DOM)
• Auth0 (authentication)
• Graph.cool (backend)
• Impagination (infinite datasets)
What should the app do?
• Login / Sign up
• See your profile & images you’ve posted
• Edit your profile
• Post a new photo
• Main list feed showing everyones posts
Web demo
Implementation
What’s the approach?
Build the web app
Start to build the native app
Realize I’ve already solved these
problems in the web app
Refactor
ListPage.js
ListPage.js handles both UI & data
right now
ListPage for native duplicates a lot
form web ListPage
class ListPage extends React.Component {
static propTypes = {
data: React.PropTypes.object,
}
state = {
dataset: null,
datasetState: null,
}
setupImpagination() {}
componentWillMount() {this.setupImpagination();}
setCurrentReadOffset = (event) => {}
render () {
return (
<div style={{maxWidth: "600px", margin: "0 auto", padding: "20px 0"}}>
<Infinite elementHeight={ITEM_HEIGHT} handleScroll={this.setCurrentReadOffset}
useWindowAsScrollContainer>
{this.state.datasetState.map(record => {
if (record.isPending && !record.isSettled) {
return <LoadingPost key={Math.random()} />;
}
return <Photo key={record.content.id} photo={record.content} user={record.content.user} />;
})}
</Infinite>
</div>
);
}
}
const FeedQuery = gql`query($skip: Int!, $first: Int!) {
allPhotos(orderBy: createdAt_DESC, first: $first, skip: $skip) {
}
}`;
export default graphql(FeedQuery, {options: {variables: { skip: 0, first: PAGE_SIZE }}})(ListPage);
Web ListPage.js
`
class ListPage extends React.Component {
static propTypes = {
data: React.PropTypes.object,
}
state = {
dataset: null,
datasetState: null,
}
setupImpagination() {}
componentWillMount() {this.setupImpagination();}
setCurrentReadOffset = (event) => {}
render () {
return (
<ScrollView style={{flex: 1}} scrollEventThrottle={300}
onScroll={this.setCurrentReadOffset} removeClippedSubviews={true}>
{this.state.datasetState.map(record => {
if(record.isPending && !record.isSettled) {
return <LoadingPost key={Math.random()}/>;
}
return <Photo key={record.content.id} photo={record.content} user={record.content.user} />;
})}
</ScrollView>
);
}
}
const FeedQuery = gql`query($skip: Int!, $first: Int!) {
allPhotos(orderBy: createdAt_DESC, first: $first, skip: $skip) {
}
}`;
export default graphql(FeedQuery, {options: {variables: { skip: 0, first: PAGE_SIZE }}})(ListPage);
Native ListPage.js
Everything but the UI is the same
New structure
Presentation & container components
<IndexRoute component={ListPageContainer} />
<Route path='feed' component={ListPageContainer} />
import ListPageView from ‘../components/presentational/ListPageView’;
class ListPageContainer extends React.Component {
state = {
dataset: null,
datasetState: null,
}
setupImpagination() {}
componentWillMount() {this.setupImpagination();}
setCurrentReadOffset = (event) => {}
render () {
return (
<ListPageView setCurrentReadOffset={this.setCurrentReadOffset}
datasetState={this.state.datasetState} />;
);
}
}
const FeedQuery = gql`query($skip: Int!, $first: Int!) {
allPhotos(orderBy: createdAt_DESC, first: $first, skip: $skip) {
}
}`;
export default graphql(FeedQuery, {options: {variables: { skip: 0, first: PAGE_SIZE }}})(ListPage);
Make the container component render
a separate presentation component
Leave setting the readOffset to the
presentation components
setCurrentReadOffset function is passed
as a prop from the container component
t
import React, { Component } from 'react';
import Infinite from 'react-infinite';
import Photo from '../presentational/Photo';
import LoadingPost from '../presentational/LoadingPost';
const ITEM_HEIGHT = 600;
const HEADER_HEIGHT = 80;
class ListPageView extends Component {
setCurrentReadOffset = (event) => {
let currentItemIndex = Math.ceil((window.scrollY - HEADER_HEIGHT) / ITEM_HEIGHT);
this.props.setCurrentReadOffset(currentItemIndex);
}
render() {
return (
<div style={{maxWidth: "600px", margin: "0 auto", padding: "20px 0"}}>
<Infinite elementHeight={ITEM_HEIGHT} handleScroll={this.setCurrentReadOffset}
useWindowAsScrollContainer>
{this.props.datasetState.map(record => {
if (record.isPending && !record.isSettled) {
return <LoadingPost key={Math.random()} />;
}
return <Photo key={record.content.id} photo={record.content}
user={record.content.user} />;
})}
</Infinite>
</div>
);
}
}
export default ListPageView;
Web presentation component
Native presentation component
import React, { Component } from 'react';
import Photo from '../presentational/Photo';
import LoadingPost from '../presentational/LoadingPost';
import {
ScrollView
} from 'react-native';
const ITEM_HEIGHT = 485;
class ListPageView extends Component {
setCurrentReadOffset = (event) => {
let currentOffset = Math.floor(event.nativeEvent.contentOffset.y);
let currentItemIndex = Math.ceil(currentOffset / ITEM_HEIGHT);
this.props.setCurrentReadOffset(currentItemIndex);
}
render() {
return (
<ScrollView style={{flex: 1}} scrollEventThrottle={300}
onScroll={this.setCurrentReadOffset} removeClippedSubviews={true}>
{this.props.datasetState.map(record => {
if(record.isPending && !record.isSettled) {
return <LoadingPost key={Math.random()}/>;
}
return <Photo key={record.content.id} photo={record.content}
user={record.content.user} />;
})}
</ScrollView>
);
}
}
export default ListPageView;
This theme continues throughout the
entire app
<IndexRoute component={ListPageContainer} />
<Route path='feed' component={ListPageContainer} />
<Route path='new' component={CreatePostContainer}
onEnter={this.requireAuth.bind(this)} />
<Route path='signup' component={CreateUserContainer} />
<Route path='profile' component={UserProfileContainer} >
<IndexRoute component={UserProfileContainer} />
<Route path='edit' component={EditProfileContainer} />
</Route>
<Route path='logout' component={() =>
<Logout logout={this.handleToken.bind(this)} />
} />
Native app demo
Postmortem
Building the apps in time was hard…
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
Figuring out what code is shareable
Figuring out how to make that code
shareable
React Router is neat & works cross
platform
There are different imports for React Native
& React
Crossing platforms with JavaScript & React
Auth0 was very easy to implement on
both platforms.
There are different APIs for React Native &
React
AsyncStorage vs localStorage
What all ended up being shared?
✅ List feed
✅ User profile
✅ Edit user profile
✅ Sign up
✅ New post
Beyond login mostly everything else is
the same
The UI changed but not the business
logic
Key takeaways
We’re in a post DOM world
Write JavaScript interaction models
The UI framework will change but the
underlying model driving it won’t
“It’s just JavaScript”
We get stronger libraries by increasing
the number of users & contributors.
React makes this very easy thanks to
React & React Native
I was able to share the same five container
components across three different platforms
Write one container component and
many UI components
The core of this app is shared
That’s a cost savings
I own this entire product & its 3
platforms
In 2 weeks I was able do all of this
Cross platform JS FTW
Instagram also agrees with me
https://engineering.instagram.com/react-native-at-instagram-
dd828a9a90c7#.i364vchox
Crossing platforms with JavaScript & React
If this kind of stuff interests you
We’re hiring!
Thanks!
@robdel12
Ad

Recommended

Integrating React.js with PHP projects
Integrating React.js with PHP projects
Ignacio Martín
 
Client-side Rendering with AngularJS
Client-side Rendering with AngularJS
David Lapsley
 
20141001 delapsley-oc-openstack-final
20141001 delapsley-oc-openstack-final
David Lapsley
 
React with Redux
React with Redux
Stanimir Todorov
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
Nelson Glauber Leal
 
Introduction to React & Redux
Introduction to React & Redux
Boris Dinkevich
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the Things
Scott Gardner
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
Roel Hartman
 
jQuery for beginners
jQuery for beginners
Divakar Gu
 
Angular Tutorial Freshers and Experienced
Angular Tutorial Freshers and Experienced
rajkamaltibacademy
 
Introduction to Redux
Introduction to Redux
Ignacio Martín
 
Backbone.js
Backbone.js
Knoldus Inc.
 
AngularJs
AngularJs
syam kumar kk
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
Unit Testing at Scale
Unit Testing at Scale
Jan Wloka
 
Test-driven Development with AEM
Test-driven Development with AEM
Jan Wloka
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJS
Jacopo Nardiello
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
Yehuda Katz
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
River of Talent
 
Basics of AngularJS
Basics of AngularJS
Filip Janevski
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
Guy Royse
 
How to build an AngularJS backend-ready app WITHOUT BACKEND
How to build an AngularJS backend-ready app WITHOUT BACKEND
Enrique Oriol Bermúdez
 
Getting Started with Combine And SwiftUI
Getting Started with Combine And SwiftUI
Scott Gardner
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and Smartphones
Michael Galpin
 
Tips for Angular Applications
Tips for Angular Applications
Sebastian Pederiva
 
Solid angular
Solid angular
Nir Kaufman
 
AngularJs Crash Course
AngularJs Crash Course
Keith Bloomfield
 
AngularJS Basics with Example
AngularJS Basics with Example
Sergey Bolshchikov
 
React vs angular (mobile first battle)
React vs angular (mobile first battle)
Michael Haberman
 
React + Redux Introduction
React + Redux Introduction
Nikolaus Graf
 

More Related Content

What's hot (20)

jQuery for beginners
jQuery for beginners
Divakar Gu
 
Angular Tutorial Freshers and Experienced
Angular Tutorial Freshers and Experienced
rajkamaltibacademy
 
Introduction to Redux
Introduction to Redux
Ignacio Martín
 
Backbone.js
Backbone.js
Knoldus Inc.
 
AngularJs
AngularJs
syam kumar kk
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
Unit Testing at Scale
Unit Testing at Scale
Jan Wloka
 
Test-driven Development with AEM
Test-driven Development with AEM
Jan Wloka
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJS
Jacopo Nardiello
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
Yehuda Katz
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
River of Talent
 
Basics of AngularJS
Basics of AngularJS
Filip Janevski
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
Guy Royse
 
How to build an AngularJS backend-ready app WITHOUT BACKEND
How to build an AngularJS backend-ready app WITHOUT BACKEND
Enrique Oriol Bermúdez
 
Getting Started with Combine And SwiftUI
Getting Started with Combine And SwiftUI
Scott Gardner
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and Smartphones
Michael Galpin
 
Tips for Angular Applications
Tips for Angular Applications
Sebastian Pederiva
 
Solid angular
Solid angular
Nir Kaufman
 
AngularJs Crash Course
AngularJs Crash Course
Keith Bloomfield
 
AngularJS Basics with Example
AngularJS Basics with Example
Sergey Bolshchikov
 
jQuery for beginners
jQuery for beginners
Divakar Gu
 
Angular Tutorial Freshers and Experienced
Angular Tutorial Freshers and Experienced
rajkamaltibacademy
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Thomas Fuchs
 
Unit Testing at Scale
Unit Testing at Scale
Jan Wloka
 
Test-driven Development with AEM
Test-driven Development with AEM
Jan Wloka
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJS
Jacopo Nardiello
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
Yehuda Katz
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
River of Talent
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
Guy Royse
 
How to build an AngularJS backend-ready app WITHOUT BACKEND
How to build an AngularJS backend-ready app WITHOUT BACKEND
Enrique Oriol Bermúdez
 
Getting Started with Combine And SwiftUI
Getting Started with Combine And SwiftUI
Scott Gardner
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and Smartphones
Michael Galpin
 

Viewers also liked (20)

React vs angular (mobile first battle)
React vs angular (mobile first battle)
Michael Haberman
 
React + Redux Introduction
React + Redux Introduction
Nikolaus Graf
 
React vs-angular-mobile
React vs-angular-mobile
Michael Haberman
 
Introduction to Facebook React
Introduction to Facebook React
Mitch Chen
 
Discover React
Discover React
Massimo Iacolare
 
Línea de Desarrollo Humano 2017
Línea de Desarrollo Humano 2017
Ep Freire
 
Southern Traditions Outdoors July - August 2016
Southern Traditions Outdoors July - August 2016
Kalli Collective
 
Animales en la Grecia Antigua
Animales en la Grecia Antigua
LUCIAVALIENTE
 
React vs Angular: ups & downs (speaker Oleksandr Kovalov, Binary Studio)
React vs Angular: ups & downs (speaker Oleksandr Kovalov, Binary Studio)
Binary Studio
 
Obra de Teatro sobre los Dioses Griegos
Obra de Teatro sobre los Dioses Griegos
LUCIAVALIENTE
 
Grupos Sociales en la Antigua Grecia
Grupos Sociales en la Antigua Grecia
LUCIAVALIENTE
 
Mitología Griega
Mitología Griega
LUCIAVALIENTE
 
¿Dónde vivían los griegos?
¿Dónde vivían los griegos?
LUCIAVALIENTE
 
Angular 2 vs React
Angular 2 vs React
Iran Reyes Fleitas
 
Learn react-js
Learn react-js
C...L, NESPRESSO, WAFAASSURANCE, SOFRECOM ORANGE
 
Introduction to react_js
Introduction to react_js
MicroPyramid .
 
Angular vs Angular 2 vs React. Сергей Александров
Angular vs Angular 2 vs React. Сергей Александров
EatDog
 
Angular js vs. Facebook react
Angular js vs. Facebook react
Keyup
 
Introduction to ReactJS
Introduction to ReactJS
Hoang Long
 
Formas poéticas
Formas poéticas
Mario Rojas
 
React vs angular (mobile first battle)
React vs angular (mobile first battle)
Michael Haberman
 
React + Redux Introduction
React + Redux Introduction
Nikolaus Graf
 
Introduction to Facebook React
Introduction to Facebook React
Mitch Chen
 
Línea de Desarrollo Humano 2017
Línea de Desarrollo Humano 2017
Ep Freire
 
Southern Traditions Outdoors July - August 2016
Southern Traditions Outdoors July - August 2016
Kalli Collective
 
Animales en la Grecia Antigua
Animales en la Grecia Antigua
LUCIAVALIENTE
 
React vs Angular: ups & downs (speaker Oleksandr Kovalov, Binary Studio)
React vs Angular: ups & downs (speaker Oleksandr Kovalov, Binary Studio)
Binary Studio
 
Obra de Teatro sobre los Dioses Griegos
Obra de Teatro sobre los Dioses Griegos
LUCIAVALIENTE
 
Grupos Sociales en la Antigua Grecia
Grupos Sociales en la Antigua Grecia
LUCIAVALIENTE
 
¿Dónde vivían los griegos?
¿Dónde vivían los griegos?
LUCIAVALIENTE
 
Introduction to react_js
Introduction to react_js
MicroPyramid .
 
Angular vs Angular 2 vs React. Сергей Александров
Angular vs Angular 2 vs React. Сергей Александров
EatDog
 
Angular js vs. Facebook react
Angular js vs. Facebook react
Keyup
 
Introduction to ReactJS
Introduction to ReactJS
Hoang Long
 
Formas poéticas
Formas poéticas
Mario Rojas
 
Ad

Similar to Crossing platforms with JavaScript & React (20)

Boosting Data Fetching in Turkish Apps with React Native and GraphQL
Boosting Data Fetching in Turkish Apps with React Native and GraphQL
Shiv Technolabs Pvt. Ltd.
 
Getting Started with Relay Modern
Getting Started with Relay Modern
Nikolas Burk
 
UI 모듈화로 워라밸 지키기
UI 모듈화로 워라밸 지키기
NAVER SHOPPING
 
React native meetup 2019
React native meetup 2019
Arjun Kava
 
Connect.js - Exploring React.Native
Connect.js - Exploring React.Native
joshcjensen
 
An Emoji Introduction to React Native (Panagiotis Vourtsis, Senior Front End ...
An Emoji Introduction to React Native (Panagiotis Vourtsis, Senior Front End ...
GreeceJS
 
Pieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React Native
tlv-ios-dev
 
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJS
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJS
Khor SoonHin
 
React Native: JS MVC Meetup #15
React Native: JS MVC Meetup #15
Rob Gietema
 
How React Native has changed Web and Mobile Application Development, Engineer...
How React Native has changed Web and Mobile Application Development, Engineer...
engineermaste solution
 
JS Fest 2018. Илья Иванов. Введение в React-Native
JS Fest 2018. Илья Иванов. Введение в React-Native
JSFestUA
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
epamspb
 
React 16: new features and beyond
React 16: new features and beyond
Artjoker
 
React native: building native iOS apps with javascript
React native: building native iOS apps with javascript
Polidea
 
Implement react pagination with react hooks and react paginate
Implement react pagination with react hooks and react paginate
Katy Slemon
 
React native
React native
Mohammed El Rafie Tarabay
 
Lecture 2 Styling and Layout in React Native.pptx
Lecture 2 Styling and Layout in React Native.pptx
GevitaChinnaiah
 
React native introduction
React native introduction
InnerFood
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React Native
Anton Kulyk
 
Academy PRO: React native - building first scenes
Academy PRO: React native - building first scenes
Binary Studio
 
Boosting Data Fetching in Turkish Apps with React Native and GraphQL
Boosting Data Fetching in Turkish Apps with React Native and GraphQL
Shiv Technolabs Pvt. Ltd.
 
Getting Started with Relay Modern
Getting Started with Relay Modern
Nikolas Burk
 
UI 모듈화로 워라밸 지키기
UI 모듈화로 워라밸 지키기
NAVER SHOPPING
 
React native meetup 2019
React native meetup 2019
Arjun Kava
 
Connect.js - Exploring React.Native
Connect.js - Exploring React.Native
joshcjensen
 
An Emoji Introduction to React Native (Panagiotis Vourtsis, Senior Front End ...
An Emoji Introduction to React Native (Panagiotis Vourtsis, Senior Front End ...
GreeceJS
 
Pieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React Native
tlv-ios-dev
 
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJS
Tokyo React.js #3: Missing Pages: ReactJS/Flux/GraphQL/RelayJS
Khor SoonHin
 
React Native: JS MVC Meetup #15
React Native: JS MVC Meetup #15
Rob Gietema
 
How React Native has changed Web and Mobile Application Development, Engineer...
How React Native has changed Web and Mobile Application Development, Engineer...
engineermaste solution
 
JS Fest 2018. Илья Иванов. Введение в React-Native
JS Fest 2018. Илья Иванов. Введение в React-Native
JSFestUA
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
epamspb
 
React 16: new features and beyond
React 16: new features and beyond
Artjoker
 
React native: building native iOS apps with javascript
React native: building native iOS apps with javascript
Polidea
 
Implement react pagination with react hooks and react paginate
Implement react pagination with react hooks and react paginate
Katy Slemon
 
Lecture 2 Styling and Layout in React Native.pptx
Lecture 2 Styling and Layout in React Native.pptx
GevitaChinnaiah
 
React native introduction
React native introduction
InnerFood
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React Native
Anton Kulyk
 
Academy PRO: React native - building first scenes
Academy PRO: React native - building first scenes
Binary Studio
 
Ad

Recently uploaded (20)

Rapid Prototyping for XR: Lecture 4 - High Level Prototyping.
Rapid Prototyping for XR: Lecture 4 - High Level Prototyping.
Mark Billinghurst
 
Rapid Prototyping for XR: Lecture 2 - Low Fidelity Prototyping.
Rapid Prototyping for XR: Lecture 2 - Low Fidelity Prototyping.
Mark Billinghurst
 
Cadastral Maps
Cadastral Maps
Google
 
Rapid Prototyping for XR: Lecture 5 - Cross Platform Development
Rapid Prototyping for XR: Lecture 5 - Cross Platform Development
Mark Billinghurst
 
retina_biometrics ruet rajshahi bangdesh.pptx
retina_biometrics ruet rajshahi bangdesh.pptx
MdRakibulIslam697135
 
May 2025: Top 10 Read Articles in Data Mining & Knowledge Management Process
May 2025: Top 10 Read Articles in Data Mining & Knowledge Management Process
IJDKP
 
machine learning is a advance technology
machine learning is a advance technology
ynancy893
 
Structural Wonderers_new and ancient.pptx
Structural Wonderers_new and ancient.pptx
nikopapa113
 
System design handwritten notes guidance
System design handwritten notes guidance
Shabista Imam
 
(Continuous Integration and Continuous Deployment/Delivery) is a fundamental ...
(Continuous Integration and Continuous Deployment/Delivery) is a fundamental ...
ketan09101
 
International Journal of Advanced Information Technology (IJAIT)
International Journal of Advanced Information Technology (IJAIT)
ijait
 
Mechanical Vibration_MIC 202_iit roorkee.pdf
Mechanical Vibration_MIC 202_iit roorkee.pdf
isahiliitr
 
Call For Papers - 17th International Conference on Wireless & Mobile Networks...
Call For Papers - 17th International Conference on Wireless & Mobile Networks...
hosseinihamid192023
 
Modern multi-proposer consensus implementations
Modern multi-proposer consensus implementations
François Garillot
 
NEW Strengthened Senior High School Gen Math.pptx
NEW Strengthened Senior High School Gen Math.pptx
DaryllWhere
 
DESIGN OF REINFORCED CONCRETE ELEMENTS S
DESIGN OF REINFORCED CONCRETE ELEMENTS S
prabhusp8
 
Generative AI & Scientific Research : Catalyst for Innovation, Ethics & Impact
Generative AI & Scientific Research : Catalyst for Innovation, Ethics & Impact
AlqualsaDIResearchGr
 
Tally.ERP 9 at a Glance.book - Tally Solutions .pdf
Tally.ERP 9 at a Glance.book - Tally Solutions .pdf
Shabista Imam
 
Industry 4.o the fourth revolutionWeek-2.pptx
Industry 4.o the fourth revolutionWeek-2.pptx
KNaveenKumarECE
 
Introduction to sensing and Week-1.pptx
Introduction to sensing and Week-1.pptx
KNaveenKumarECE
 
Rapid Prototyping for XR: Lecture 4 - High Level Prototyping.
Rapid Prototyping for XR: Lecture 4 - High Level Prototyping.
Mark Billinghurst
 
Rapid Prototyping for XR: Lecture 2 - Low Fidelity Prototyping.
Rapid Prototyping for XR: Lecture 2 - Low Fidelity Prototyping.
Mark Billinghurst
 
Cadastral Maps
Cadastral Maps
Google
 
Rapid Prototyping for XR: Lecture 5 - Cross Platform Development
Rapid Prototyping for XR: Lecture 5 - Cross Platform Development
Mark Billinghurst
 
retina_biometrics ruet rajshahi bangdesh.pptx
retina_biometrics ruet rajshahi bangdesh.pptx
MdRakibulIslam697135
 
May 2025: Top 10 Read Articles in Data Mining & Knowledge Management Process
May 2025: Top 10 Read Articles in Data Mining & Knowledge Management Process
IJDKP
 
machine learning is a advance technology
machine learning is a advance technology
ynancy893
 
Structural Wonderers_new and ancient.pptx
Structural Wonderers_new and ancient.pptx
nikopapa113
 
System design handwritten notes guidance
System design handwritten notes guidance
Shabista Imam
 
(Continuous Integration and Continuous Deployment/Delivery) is a fundamental ...
(Continuous Integration and Continuous Deployment/Delivery) is a fundamental ...
ketan09101
 
International Journal of Advanced Information Technology (IJAIT)
International Journal of Advanced Information Technology (IJAIT)
ijait
 
Mechanical Vibration_MIC 202_iit roorkee.pdf
Mechanical Vibration_MIC 202_iit roorkee.pdf
isahiliitr
 
Call For Papers - 17th International Conference on Wireless & Mobile Networks...
Call For Papers - 17th International Conference on Wireless & Mobile Networks...
hosseinihamid192023
 
Modern multi-proposer consensus implementations
Modern multi-proposer consensus implementations
François Garillot
 
NEW Strengthened Senior High School Gen Math.pptx
NEW Strengthened Senior High School Gen Math.pptx
DaryllWhere
 
DESIGN OF REINFORCED CONCRETE ELEMENTS S
DESIGN OF REINFORCED CONCRETE ELEMENTS S
prabhusp8
 
Generative AI & Scientific Research : Catalyst for Innovation, Ethics & Impact
Generative AI & Scientific Research : Catalyst for Innovation, Ethics & Impact
AlqualsaDIResearchGr
 
Tally.ERP 9 at a Glance.book - Tally Solutions .pdf
Tally.ERP 9 at a Glance.book - Tally Solutions .pdf
Shabista Imam
 
Industry 4.o the fourth revolutionWeek-2.pptx
Industry 4.o the fourth revolutionWeek-2.pptx
KNaveenKumarECE
 
Introduction to sensing and Week-1.pptx
Introduction to sensing and Week-1.pptx
KNaveenKumarECE
 

Crossing platforms with JavaScript & React

  • 4. Web
  • 6. iOS
  • 10. What is cross platform JS?
  • 11. JS that can run on more than one platform
  • 13. “Why did the iOS team implement it like this?”
  • 14. “The Android app currently doesn’t support that”
  • 16. Easier to share code across many teams
  • 17. More team collaboration since there’s more overlap
  • 18. It allows teams to own products & not be separated by technology
  • 19. TL;DR your team now owns the iOS, Android, and (maybe) web apps.
  • 22. If you can build iOS & Android apps in the same code base it should be cheaper
  • 23. Why not bet on the web?
  • 24. Native will be better than mobile web for a while
  • 25. Why not take the web tooling & get native results?
  • 26. You are betting on the web
  • 27. Can’t beat them, join them
  • 28. I decided to be ambitious
  • 29. Build an Instagram clone for Web, iOS, & Android
  • 31. Use Impagination.js to power an Infinite scroll of images
  • 33. Impagination will work on any JS codebase
  • 34. Building infinite scroll in React Native with Impagination http://bit.ly/reactnativeinfinitescroll
  • 35. We’ve already used Impagination in four different platforms
  • 36. What else can be shared?
  • 39. Three phases to the experiment • Planning • Implementation • Postmortem
  • 42. 🥞The stack🥞 • React Native • React (DOM) • Auth0 (authentication) • Graph.cool (backend) • Impagination (infinite datasets)
  • 43. What should the app do? • Login / Sign up • See your profile & images you’ve posted • Edit your profile • Post a new photo • Main list feed showing everyones posts
  • 48. Start to build the native app
  • 49. Realize I’ve already solved these problems in the web app
  • 52. ListPage.js handles both UI & data right now
  • 53. ListPage for native duplicates a lot form web ListPage
  • 54. class ListPage extends React.Component { static propTypes = { data: React.PropTypes.object, } state = { dataset: null, datasetState: null, } setupImpagination() {} componentWillMount() {this.setupImpagination();} setCurrentReadOffset = (event) => {} render () { return ( <div style={{maxWidth: "600px", margin: "0 auto", padding: "20px 0"}}> <Infinite elementHeight={ITEM_HEIGHT} handleScroll={this.setCurrentReadOffset} useWindowAsScrollContainer> {this.state.datasetState.map(record => { if (record.isPending && !record.isSettled) { return <LoadingPost key={Math.random()} />; } return <Photo key={record.content.id} photo={record.content} user={record.content.user} />; })} </Infinite> </div> ); } } const FeedQuery = gql`query($skip: Int!, $first: Int!) { allPhotos(orderBy: createdAt_DESC, first: $first, skip: $skip) { } }`; export default graphql(FeedQuery, {options: {variables: { skip: 0, first: PAGE_SIZE }}})(ListPage); Web ListPage.js
  • 55. ` class ListPage extends React.Component { static propTypes = { data: React.PropTypes.object, } state = { dataset: null, datasetState: null, } setupImpagination() {} componentWillMount() {this.setupImpagination();} setCurrentReadOffset = (event) => {} render () { return ( <ScrollView style={{flex: 1}} scrollEventThrottle={300} onScroll={this.setCurrentReadOffset} removeClippedSubviews={true}> {this.state.datasetState.map(record => { if(record.isPending && !record.isSettled) { return <LoadingPost key={Math.random()}/>; } return <Photo key={record.content.id} photo={record.content} user={record.content.user} />; })} </ScrollView> ); } } const FeedQuery = gql`query($skip: Int!, $first: Int!) { allPhotos(orderBy: createdAt_DESC, first: $first, skip: $skip) { } }`; export default graphql(FeedQuery, {options: {variables: { skip: 0, first: PAGE_SIZE }}})(ListPage); Native ListPage.js
  • 56. Everything but the UI is the same
  • 59. <IndexRoute component={ListPageContainer} /> <Route path='feed' component={ListPageContainer} />
  • 60. import ListPageView from ‘../components/presentational/ListPageView’; class ListPageContainer extends React.Component { state = { dataset: null, datasetState: null, } setupImpagination() {} componentWillMount() {this.setupImpagination();} setCurrentReadOffset = (event) => {} render () { return ( <ListPageView setCurrentReadOffset={this.setCurrentReadOffset} datasetState={this.state.datasetState} />; ); } } const FeedQuery = gql`query($skip: Int!, $first: Int!) { allPhotos(orderBy: createdAt_DESC, first: $first, skip: $skip) { } }`; export default graphql(FeedQuery, {options: {variables: { skip: 0, first: PAGE_SIZE }}})(ListPage);
  • 61. Make the container component render a separate presentation component
  • 62. Leave setting the readOffset to the presentation components
  • 63. setCurrentReadOffset function is passed as a prop from the container component
  • 64. t import React, { Component } from 'react'; import Infinite from 'react-infinite'; import Photo from '../presentational/Photo'; import LoadingPost from '../presentational/LoadingPost'; const ITEM_HEIGHT = 600; const HEADER_HEIGHT = 80; class ListPageView extends Component { setCurrentReadOffset = (event) => { let currentItemIndex = Math.ceil((window.scrollY - HEADER_HEIGHT) / ITEM_HEIGHT); this.props.setCurrentReadOffset(currentItemIndex); } render() { return ( <div style={{maxWidth: "600px", margin: "0 auto", padding: "20px 0"}}> <Infinite elementHeight={ITEM_HEIGHT} handleScroll={this.setCurrentReadOffset} useWindowAsScrollContainer> {this.props.datasetState.map(record => { if (record.isPending && !record.isSettled) { return <LoadingPost key={Math.random()} />; } return <Photo key={record.content.id} photo={record.content} user={record.content.user} />; })} </Infinite> </div> ); } } export default ListPageView; Web presentation component
  • 65. Native presentation component import React, { Component } from 'react'; import Photo from '../presentational/Photo'; import LoadingPost from '../presentational/LoadingPost'; import { ScrollView } from 'react-native'; const ITEM_HEIGHT = 485; class ListPageView extends Component { setCurrentReadOffset = (event) => { let currentOffset = Math.floor(event.nativeEvent.contentOffset.y); let currentItemIndex = Math.ceil(currentOffset / ITEM_HEIGHT); this.props.setCurrentReadOffset(currentItemIndex); } render() { return ( <ScrollView style={{flex: 1}} scrollEventThrottle={300} onScroll={this.setCurrentReadOffset} removeClippedSubviews={true}> {this.props.datasetState.map(record => { if(record.isPending && !record.isSettled) { return <LoadingPost key={Math.random()}/>; } return <Photo key={record.content.id} photo={record.content} user={record.content.user} />; })} </ScrollView> ); } } export default ListPageView;
  • 66. This theme continues throughout the entire app
  • 67. <IndexRoute component={ListPageContainer} /> <Route path='feed' component={ListPageContainer} /> <Route path='new' component={CreatePostContainer} onEnter={this.requireAuth.bind(this)} /> <Route path='signup' component={CreateUserContainer} /> <Route path='profile' component={UserProfileContainer} > <IndexRoute component={UserProfileContainer} /> <Route path='edit' component={EditProfileContainer} /> </Route> <Route path='logout' component={() => <Logout logout={this.handleToken.bind(this)} /> } />
  • 70. Building the apps in time was hard…
  • 73. Figuring out what code is shareable
  • 74. Figuring out how to make that code shareable
  • 75. React Router is neat & works cross platform There are different imports for React Native & React
  • 77. Auth0 was very easy to implement on both platforms. There are different APIs for React Native & React
  • 79. What all ended up being shared?
  • 80. ✅ List feed ✅ User profile ✅ Edit user profile ✅ Sign up ✅ New post
  • 81. Beyond login mostly everything else is the same
  • 82. The UI changed but not the business logic
  • 84. We’re in a post DOM world
  • 86. The UI framework will change but the underlying model driving it won’t
  • 88. We get stronger libraries by increasing the number of users & contributors.
  • 89. React makes this very easy thanks to React & React Native
  • 90. I was able to share the same five container components across three different platforms
  • 91. Write one container component and many UI components
  • 92. The core of this app is shared
  • 93. That’s a cost savings
  • 94. I own this entire product & its 3 platforms
  • 95. In 2 weeks I was able do all of this
  • 97. Instagram also agrees with me https://engineering.instagram.com/react-native-at-instagram- dd828a9a90c7#.i364vchox
  • 99. If this kind of stuff interests you