SlideShare a Scribd company logo
1 of 35
One code Web, iOS, Android
Artem Marchenko, 09 Feb 2017
https://twitter.com/AgileArtem
Artem
https://twitter.com/AgileArtem
• Buzzwords:
– Interactive images, Qt/QML, Jolla SailfishOS, Agile-
shmagile, TDD, product management, JavaScript, Java,
whatever works, prototyping, startups, paragliding, salsa
dancing, ReactJS, React Native
– http://www.thinglink.com
• Twitter: @AgileArtem
Подорожник
https://twitter.com/AgileArtem
Подорожник – калькулятор
https://twitter.com/AgileArtem
Подорожник – калькулятор
https://twitter.com/AgileArtem
Actually usable
https://twitter.com/AgileArtem
WHAT’S UNDER COVER
https://twitter.com/AgileArtem
Under the cover
https://twitter.com/AgileArtem
App structure
https://twitter.com/AgileArtem
index.js
index.ios.js
index.androi
d.js
native/
AppContainer
AppContainer
Other web UI
components
Other native
UI
components
web reducers
common
reducer
native
reducers
native-
specific
reducer (e.g.
orientation
change)
Project structure
- src
- native
- components
- styles
- util
- web
- components
- test
- web
- components
https://twitter.com/AgileArtem
WHAT WORKED
https://twitter.com/AgileArtem
Google Analytics: Mobile
react-native-google-analytics-bridge
• Worked as simple as
const GA = require('react-native-google-
analytics-bridge');
const GA_TRACKER_ID = Platform.OS === 'ios'
? 'UA-76217125-6' : 'UA-76217125-5';
GA.setTrackerId( GA_TRACKER_ID );
GA.trackEvent('general', 'app: activated');
https://twitter.com/AgileArtem
Mobile Ads: Google AdMob
react-native-admob
Converting default React Native iOS project to pods/workspace
can be challenging, but then the usage is super-simple
import { AdMobBanner } from 'react-native-admob’;
<AdMobBanner
style={appStyle.bottomBanner}
bannerSize={"smartBannerPortrait"}
adUnitID={"ca-app-pub-
6248714847105943/1045980532"}
didFailToReceiveAdWithError={this.bannerError}
/>
https://twitter.com/AgileArtem
Redux and Redux Dev Tools
• Redux (or Flux if you like) could be the best
part of React practice actually
https://twitter.com/AgileArtem
WHAT WORKED OKAYISH
https://twitter.com/AgileArtem
Redux. Good parts
• Redux is awesome.
• Debugging dumb structures, tracing changes
message by message and time traveling is
simple and efficient
• Definitely use Redux Dev Tools (e.g. as a
Chrome extension)
https://twitter.com/AgileArtem
Redux. Complexities
• Making Redux, routing and Local Storage like
each other was pain in the bottom and rain
dances
– There is logic certainly, but you’ll either need to learn
a lot of it or dance around and hope
– Or clone my solution, but be aware it’s coding by
accident
• Modifying several files in the different parts of
code base (action creator, reducer, handler) for
just passing same stuff around is a lot of error
prone typing.
– Consider ducks approach – all the code about one bit
of functionality together
https://twitter.com/AgileArtem
Redux: more mistakes
• Do not store UI state (screen size) or
computable data (final price) in the model
• Use memoizable redux selectors for it (e.g.
reselect).
– Looks the same, feels the same, but you do not
pollute the model with the data to keep in sync
https://twitter.com/AgileArtem
Immutable.JS
const calcedPaymentState =
preUpdatedState.setIn(['paymentOptions', 'eTicket',
'totalCost'], newETicketCost)
• State that’s guaranteed to be immutable is way easier to
debug
• But not all the components are ready for it out of the box and
want to see plain JS objects (I had issues with browserHistory I
think)
• And on a small research-like app you might not see benefits of
immutability yet while you might hit the integration obstacles
https://twitter.com/AgileArtem
Routing and browse and sharable urls
import { Router, Route, IndexRoute, browserHistory, useRouterHistory } from 'react-
router';
import { routerMiddleware, syncHistoryWithStore, routerReducer, push } from 'react-
router-redux';
import createBrowserHistory from 'history/lib/createBrowserHistory';
const queryString = require('query-string');
const history = syncHistoryWithStore(browserHistory, store,
{selectLocationState: (state) => {
const r = state.getIn(['metadata', 'routing']);
return r || '/';
}});
const routedState = state.setIn(['metadata', 'routing'], {
locationBeforeTransitions: {
pathname: '/',
search: searchString,
query: {},
hash: ''
}
}) https://twitter.com/AgileArtem
Routing and browse and sharable urls
• React Router is okay, browserHistory is okay, storing routing in a
storage is okay, but making it work together is tough
– Especially if some more middleware is involved: Redux Dev Tools
• I used query string as the initial boss that commanded the state
that was setting up the routing
– Then state updates are changing the browserHistory-specific keys.
browserHistory was updating the address bar
• And there are WebKit bugs features. You cannot update URL too
often
• Use my solution if you just want things to work
– Yet it’s programming by accident
https://twitter.com/AgileArtem
Structuring controls for testing
• Simple, isolates core part for testability, but I didn’t use
much testing in the end
– Started from awesome tutorial by a Finn
@teropahttp://teropa.info/blog/2015/09/10/full-stack-
redux-tutorial.html
export class InputBlock extends React.Component {
constructor(props) {
…
export const InputBlockContainer = connect(
mapStateToProps,
actionCreators
)(InputBlock);
https://twitter.com/AgileArtem
Using template for injecting stuff into
the web root
var HtmlWebpackPlugin = require('html-webpack-plugin');
…
new HtmlWebpackPlugin({
inject: false,
template: 'src/web/index.ejs',
googleAnalytics: {
trackingId: 'UA-76217125-4',
pageViewOnLoad: true
},
…
<% if
(htmlWebpackPlugin.options.googleAnalytics.trackingId) {
%>
ga('create', '<%=
htmlWebpackPlugin.options.googleAnalytics.trackingId%>',
'auto'); https://twitter.com/AgileArtem
Title/Nav bar
react-native-navbar
• Surprisingly difficult to do in crosplatform way
• react-native-navbar works, but don’t expect to
fool a maniacal designer
https://twitter.com/AgileArtem
Portrait-Landscape layouting and
*cascading* styles
react-native-media-queries
• Works, but you may need to track rotation yourself
• Not exactly full. E.g. no difference between min-width and
min-device-width
const baseStyle = {
podorozhnikAppView: {
flexDirection: 'column',
…
export const appStyle = createStyles(
baseStyle,
maxHeight(400, {
optionsBlock: {
marginTop: 0,
…
https://twitter.com/AgileArtem
Portrait-Landscape layouting and
*cascading* styles
<View
style={appStyle.podorozhnikAppView}
onLayout={(e) => {
if(this.props.onAppLayout) {
this.props.onAppLayout({
width:
e.nativeEvent.layout.width,
height:
e.nativeEvent.layout.height
});
https://twitter.com/AgileArtem
Autostoring redux data to localStorage
import * as storage from 'redux-storage';
import createEngine from 'redux-storage-engine-
reactnativeasyncstorage';
import merger from 'redux-storage-merger-
immutablejs';
• Just works
• Mobile app only implementation
• Immutable JS was an issue here. As restoring
data was trying to overwrite the model
https://twitter.com/AgileArtem
WHAT NOT TO FOLLOW
https://twitter.com/AgileArtem
WebViews on the app side for the web
services
• I tried one for disqus
• Bad idea. Slow, error prone, hard to debug
and fix
https://twitter.com/AgileArtem
A note on testing
• I love automated structured testing so much that for
Jolla Sailfish OS I baked HelloWorld wizard that
includes testing of engine, UI, C++, JavaScript, whatnot.
• Started in full testing more in ReactJS/Native and..
• Nearly completely dropped in the end
• For the relatively simple UI-intensive project Redux
with its DevTools lets you identify and fix issues faster
than tests would have prevented them
• In a bigger project with collaborators and less core
research I’d use auto testing though
https://twitter.com/AgileArtem
iPad layout
• Didn’t work
• Seems to be possible, but solution I used
results in the iPhone mode
https://twitter.com/AgileArtem
Same code for React app on the web,
iOS, Android
• Yes
• No
• Maybe
• You are only going to really benefit from the
logic part only
• iOS and Android are close enough for sharing
almost everything
https://twitter.com/AgileArtem
WHAT NEXT
https://twitter.com/AgileArtem
Next project: compare medicine or
alcohol prices around you. Anybody
in?
https://twitter.com/AgileArtem
Contacts
• https://podorozhnik.firebaseapp.com
• https://itunes.apple.com/ru/app/podoroznik-kal-
kulator/id1107432204
• https://play.google.com/store/apps/details?id=com.art
emmarchenko.podorozhnik
• https://twitter.com/AgileArtem
• http://github.com/amarchen
• http://www.codingsubmarine.com
• http://www.agilesoftwaredevelopment.com
https://twitter.com/AgileArtem

More Related Content

What's hot

Webdriver cheatsheets summary
Webdriver cheatsheets summaryWebdriver cheatsheets summary
Webdriver cheatsheets summaryAlan Richardson
 
Optimizing React Native views for pre-animation
Optimizing React Native views for pre-animationOptimizing React Native views for pre-animation
Optimizing React Native views for pre-animationModusJesus
 
Rapidly scaffold your frontend with yeoman
Rapidly scaffold your frontend with yeomanRapidly scaffold your frontend with yeoman
Rapidly scaffold your frontend with yeomanSimon Waibl
 
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016Matt Raible
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...Matt Raible
 
Vuejs getting-started - Extended Version
Vuejs getting-started - Extended VersionVuejs getting-started - Extended Version
Vuejs getting-started - Extended VersionMurat Doğan
 
Introducing Playwright's New Test Runner
Introducing Playwright's New Test RunnerIntroducing Playwright's New Test Runner
Introducing Playwright's New Test RunnerApplitools
 
The Gist of React Native
The Gist of React NativeThe Gist of React Native
The Gist of React NativeDarren Cruse
 
E2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
E2E testing Single Page Apps and APIs with Cucumber.js and PuppeteerE2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
E2E testing Single Page Apps and APIs with Cucumber.js and PuppeteerPaul Jensen
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx 2015
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx 2015Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx 2015
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx 2015Matt Raible
 
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...Paul Jensen
 
Lo mejor y peor de React Native @ValenciaJS
Lo mejor y peor de React Native @ValenciaJSLo mejor y peor de React Native @ValenciaJS
Lo mejor y peor de React Native @ValenciaJSMarcel Kalveram
 
Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Fwdays
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016Matt Raible
 
From zero to hero with React Native!
From zero to hero with React Native!From zero to hero with React Native!
From zero to hero with React Native!Commit University
 
Automation Abstractions: Page Objects and Beyond
Automation Abstractions: Page Objects and BeyondAutomation Abstractions: Page Objects and Beyond
Automation Abstractions: Page Objects and BeyondTechWell
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 -  Fullstack end-to-end Test Automation with node.jsForwardJS 2017 -  Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.jsMek Srunyu Stittri
 

What's hot (20)

Webdriver cheatsheets summary
Webdriver cheatsheets summaryWebdriver cheatsheets summary
Webdriver cheatsheets summary
 
Optimizing React Native views for pre-animation
Optimizing React Native views for pre-animationOptimizing React Native views for pre-animation
Optimizing React Native views for pre-animation
 
Rapidly scaffold your frontend with yeoman
Rapidly scaffold your frontend with yeomanRapidly scaffold your frontend with yeoman
Rapidly scaffold your frontend with yeoman
 
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Rich Web Experie...
 
Top 8 Ruby on Rails Gems
Top 8 Ruby on Rails GemsTop 8 Ruby on Rails Gems
Top 8 Ruby on Rails Gems
 
Vuejs getting-started - Extended Version
Vuejs getting-started - Extended VersionVuejs getting-started - Extended Version
Vuejs getting-started - Extended Version
 
Introducing Playwright's New Test Runner
Introducing Playwright's New Test RunnerIntroducing Playwright's New Test Runner
Introducing Playwright's New Test Runner
 
The Gist of React Native
The Gist of React NativeThe Gist of React Native
The Gist of React Native
 
E2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
E2E testing Single Page Apps and APIs with Cucumber.js and PuppeteerE2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
E2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx 2015
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx 2015Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx 2015
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx 2015
 
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
 
React Native
React NativeReact Native
React Native
 
Lo mejor y peor de React Native @ValenciaJS
Lo mejor y peor de React Native @ValenciaJSLo mejor y peor de React Native @ValenciaJS
Lo mejor y peor de React Native @ValenciaJS
 
Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
 
From zero to hero with React Native!
From zero to hero with React Native!From zero to hero with React Native!
From zero to hero with React Native!
 
Automation Abstractions: Page Objects and Beyond
Automation Abstractions: Page Objects and BeyondAutomation Abstractions: Page Objects and Beyond
Automation Abstractions: Page Objects and Beyond
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 -  Fullstack end-to-end Test Automation with node.jsForwardJS 2017 -  Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
 

Viewers also liked

Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!cyrilpicat
 
How to improve code quality for iOS apps?
How to improve code quality for iOS apps?How to improve code quality for iOS apps?
How to improve code quality for iOS apps?Kate Semizhon
 
LinkedIn Mobile: How do we do it?
LinkedIn Mobile: How do we do it?LinkedIn Mobile: How do we do it?
LinkedIn Mobile: How do we do it?phegaro
 
iOS Design to Code - Design
iOS Design to Code - DesigniOS Design to Code - Design
iOS Design to Code - DesignLiyao Chen
 
iOS Design to Code - Code
iOS Design to Code - CodeiOS Design to Code - Code
iOS Design to Code - CodeLiyao Chen
 

Viewers also liked (8)

Code Quality Management iOS
Code Quality Management iOSCode Quality Management iOS
Code Quality Management iOS
 
Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!Make use of Sonar for your mobile developments - It's easy and useful!
Make use of Sonar for your mobile developments - It's easy and useful!
 
Code Review for iOS
Code Review for iOSCode Review for iOS
Code Review for iOS
 
How to improve code quality for iOS apps?
How to improve code quality for iOS apps?How to improve code quality for iOS apps?
How to improve code quality for iOS apps?
 
LinkedIn Mobile: How do we do it?
LinkedIn Mobile: How do we do it?LinkedIn Mobile: How do we do it?
LinkedIn Mobile: How do we do it?
 
Code Review
Code ReviewCode Review
Code Review
 
iOS Design to Code - Design
iOS Design to Code - DesigniOS Design to Code - Design
iOS Design to Code - Design
 
iOS Design to Code - Code
iOS Design to Code - CodeiOS Design to Code - Code
iOS Design to Code - Code
 

Similar to One code Web, iOS, Android

Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]GDSC UofT Mississauga
 
Introduction to react native with redux
Introduction to react native with reduxIntroduction to react native with redux
Introduction to react native with reduxMike Melusky
 
WebTest - Efficient Functional Web Testing with HtmlUnit and Beyond
WebTest - Efficient Functional Web Testing with HtmlUnit and BeyondWebTest - Efficient Functional Web Testing with HtmlUnit and Beyond
WebTest - Efficient Functional Web Testing with HtmlUnit and Beyondmguillem
 
Frontend microservices: architectures and solutions
Frontend microservices: architectures and solutionsFrontend microservices: architectures and solutions
Frontend microservices: architectures and solutionsMikhail Kuznetcov
 
An Introduction to Web Components
An Introduction to Web ComponentsAn Introduction to Web Components
An Introduction to Web ComponentsRed Pill Now
 
Introduction to web application development with Vue (for absolute beginners)...
Introduction to web application development with Vue (for absolute beginners)...Introduction to web application development with Vue (for absolute beginners)...
Introduction to web application development with Vue (for absolute beginners)...Lucas Jellema
 
Front End Development for Back End Developers - vJUG24 2017
Front End Development for Back End Developers - vJUG24 2017Front End Development for Back End Developers - vJUG24 2017
Front End Development for Back End Developers - vJUG24 2017Matt Raible
 
Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Matt Raible
 
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer ReplacementMidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer ReplacementZach Lendon
 
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)Zach Lendon
 
Professionalizing the Front-end
Professionalizing the Front-endProfessionalizing the Front-end
Professionalizing the Front-endJordi Anguela
 
Pain Driven Development by Alexandr Sugak
Pain Driven Development by Alexandr SugakPain Driven Development by Alexandr Sugak
Pain Driven Development by Alexandr SugakSigma Software
 
LvivCSS: Web Components as a foundation for Design System
LvivCSS: Web Components as a foundation for Design SystemLvivCSS: Web Components as a foundation for Design System
LvivCSS: Web Components as a foundation for Design SystemVlad Fedosov
 
Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011Timothy Fisher
 
Untangling spring week5
Untangling spring week5Untangling spring week5
Untangling spring week5Derek Jacoby
 
Passionate People Meetup - React vs Vue with a deepdive into Proxies
Passionate People Meetup - React vs Vue with a deepdive into ProxiesPassionate People Meetup - React vs Vue with a deepdive into Proxies
Passionate People Meetup - React vs Vue with a deepdive into ProxiesHarijs Deksnis
 
Testable client side_mvc_apps_in_javascript
Testable client side_mvc_apps_in_javascriptTestable client side_mvc_apps_in_javascript
Testable client side_mvc_apps_in_javascriptTimothy Oxley
 
ReactJS vs AngularJS - Head to Head comparison
ReactJS vs AngularJS - Head to Head comparisonReactJS vs AngularJS - Head to Head comparison
ReactJS vs AngularJS - Head to Head comparison500Tech
 

Similar to One code Web, iOS, Android (20)

Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]Full Stack React Workshop [CSSC x GDSC]
Full Stack React Workshop [CSSC x GDSC]
 
Introduction to react native with redux
Introduction to react native with reduxIntroduction to react native with redux
Introduction to react native with redux
 
WebTest - Efficient Functional Web Testing with HtmlUnit and Beyond
WebTest - Efficient Functional Web Testing with HtmlUnit and BeyondWebTest - Efficient Functional Web Testing with HtmlUnit and Beyond
WebTest - Efficient Functional Web Testing with HtmlUnit and Beyond
 
Frontend microservices: architectures and solutions
Frontend microservices: architectures and solutionsFrontend microservices: architectures and solutions
Frontend microservices: architectures and solutions
 
An Introduction to Web Components
An Introduction to Web ComponentsAn Introduction to Web Components
An Introduction to Web Components
 
Introduction to web application development with Vue (for absolute beginners)...
Introduction to web application development with Vue (for absolute beginners)...Introduction to web application development with Vue (for absolute beginners)...
Introduction to web application development with Vue (for absolute beginners)...
 
Front End Development for Back End Developers - vJUG24 2017
Front End Development for Back End Developers - vJUG24 2017Front End Development for Back End Developers - vJUG24 2017
Front End Development for Back End Developers - vJUG24 2017
 
Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017Front End Development for Back End Developers - UberConf 2017
Front End Development for Back End Developers - UberConf 2017
 
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer ReplacementMidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
 
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
 
Professionalizing the Front-end
Professionalizing the Front-endProfessionalizing the Front-end
Professionalizing the Front-end
 
Pain Driven Development by Alexandr Sugak
Pain Driven Development by Alexandr SugakPain Driven Development by Alexandr Sugak
Pain Driven Development by Alexandr Sugak
 
React.js at Cortex
React.js at CortexReact.js at Cortex
React.js at Cortex
 
LvivCSS: Web Components as a foundation for Design System
LvivCSS: Web Components as a foundation for Design SystemLvivCSS: Web Components as a foundation for Design System
LvivCSS: Web Components as a foundation for Design System
 
Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011
 
Untangling spring week5
Untangling spring week5Untangling spring week5
Untangling spring week5
 
Passionate People Meetup - React vs Vue with a deepdive into Proxies
Passionate People Meetup - React vs Vue with a deepdive into ProxiesPassionate People Meetup - React vs Vue with a deepdive into Proxies
Passionate People Meetup - React vs Vue with a deepdive into Proxies
 
Testable client side_mvc_apps_in_javascript
Testable client side_mvc_apps_in_javascriptTestable client side_mvc_apps_in_javascript
Testable client side_mvc_apps_in_javascript
 
Android crash course
Android crash courseAndroid crash course
Android crash course
 
ReactJS vs AngularJS - Head to Head comparison
ReactJS vs AngularJS - Head to Head comparisonReactJS vs AngularJS - Head to Head comparison
ReactJS vs AngularJS - Head to Head comparison
 

More from Artem Marchenko

Getting started with coding for Jolla Sailfish OS. 29 Mar 2014, Tampere, Finland
Getting started with coding for Jolla Sailfish OS. 29 Mar 2014, Tampere, FinlandGetting started with coding for Jolla Sailfish OS. 29 Mar 2014, Tampere, Finland
Getting started with coding for Jolla Sailfish OS. 29 Mar 2014, Tampere, FinlandArtem Marchenko
 
Getting started with coding for Jolla Sailfish OS. 22 Feb 2014, Tampere, Finland
Getting started with coding for Jolla Sailfish OS. 22 Feb 2014, Tampere, FinlandGetting started with coding for Jolla Sailfish OS. 22 Feb 2014, Tampere, Finland
Getting started with coding for Jolla Sailfish OS. 22 Feb 2014, Tampere, FinlandArtem Marchenko
 
Misapplied Scrum pattern
Misapplied Scrum patternMisapplied Scrum pattern
Misapplied Scrum patternArtem Marchenko
 
Effective Software Development for the 21st century
Effective Software Development for the 21st centuryEffective Software Development for the 21st century
Effective Software Development for the 21st centuryArtem Marchenko
 

More from Artem Marchenko (7)

Getting started with coding for Jolla Sailfish OS. 29 Mar 2014, Tampere, Finland
Getting started with coding for Jolla Sailfish OS. 29 Mar 2014, Tampere, FinlandGetting started with coding for Jolla Sailfish OS. 29 Mar 2014, Tampere, Finland
Getting started with coding for Jolla Sailfish OS. 29 Mar 2014, Tampere, Finland
 
Getting started with coding for Jolla Sailfish OS. 22 Feb 2014, Tampere, Finland
Getting started with coding for Jolla Sailfish OS. 22 Feb 2014, Tampere, FinlandGetting started with coding for Jolla Sailfish OS. 22 Feb 2014, Tampere, Finland
Getting started with coding for Jolla Sailfish OS. 22 Feb 2014, Tampere, Finland
 
Test driving-qml
Test driving-qmlTest driving-qml
Test driving-qml
 
Test driving-qml
Test driving-qmlTest driving-qml
Test driving-qml
 
Test driving QML
Test driving QMLTest driving QML
Test driving QML
 
Misapplied Scrum pattern
Misapplied Scrum patternMisapplied Scrum pattern
Misapplied Scrum pattern
 
Effective Software Development for the 21st century
Effective Software Development for the 21st centuryEffective Software Development for the 21st century
Effective Software Development for the 21st century
 

Recently uploaded

WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxAnnaArtyushina1
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 

Recently uploaded (20)

WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 

One code Web, iOS, Android

  • 1. One code Web, iOS, Android Artem Marchenko, 09 Feb 2017 https://twitter.com/AgileArtem
  • 2. Artem https://twitter.com/AgileArtem • Buzzwords: – Interactive images, Qt/QML, Jolla SailfishOS, Agile- shmagile, TDD, product management, JavaScript, Java, whatever works, prototyping, startups, paragliding, salsa dancing, ReactJS, React Native – http://www.thinglink.com • Twitter: @AgileArtem
  • 9. App structure https://twitter.com/AgileArtem index.js index.ios.js index.androi d.js native/ AppContainer AppContainer Other web UI components Other native UI components web reducers common reducer native reducers native- specific reducer (e.g. orientation change)
  • 10. Project structure - src - native - components - styles - util - web - components - test - web - components https://twitter.com/AgileArtem
  • 12. Google Analytics: Mobile react-native-google-analytics-bridge • Worked as simple as const GA = require('react-native-google- analytics-bridge'); const GA_TRACKER_ID = Platform.OS === 'ios' ? 'UA-76217125-6' : 'UA-76217125-5'; GA.setTrackerId( GA_TRACKER_ID ); GA.trackEvent('general', 'app: activated'); https://twitter.com/AgileArtem
  • 13. Mobile Ads: Google AdMob react-native-admob Converting default React Native iOS project to pods/workspace can be challenging, but then the usage is super-simple import { AdMobBanner } from 'react-native-admob’; <AdMobBanner style={appStyle.bottomBanner} bannerSize={"smartBannerPortrait"} adUnitID={"ca-app-pub- 6248714847105943/1045980532"} didFailToReceiveAdWithError={this.bannerError} /> https://twitter.com/AgileArtem
  • 14. Redux and Redux Dev Tools • Redux (or Flux if you like) could be the best part of React practice actually https://twitter.com/AgileArtem
  • 16. Redux. Good parts • Redux is awesome. • Debugging dumb structures, tracing changes message by message and time traveling is simple and efficient • Definitely use Redux Dev Tools (e.g. as a Chrome extension) https://twitter.com/AgileArtem
  • 17. Redux. Complexities • Making Redux, routing and Local Storage like each other was pain in the bottom and rain dances – There is logic certainly, but you’ll either need to learn a lot of it or dance around and hope – Or clone my solution, but be aware it’s coding by accident • Modifying several files in the different parts of code base (action creator, reducer, handler) for just passing same stuff around is a lot of error prone typing. – Consider ducks approach – all the code about one bit of functionality together https://twitter.com/AgileArtem
  • 18. Redux: more mistakes • Do not store UI state (screen size) or computable data (final price) in the model • Use memoizable redux selectors for it (e.g. reselect). – Looks the same, feels the same, but you do not pollute the model with the data to keep in sync https://twitter.com/AgileArtem
  • 19. Immutable.JS const calcedPaymentState = preUpdatedState.setIn(['paymentOptions', 'eTicket', 'totalCost'], newETicketCost) • State that’s guaranteed to be immutable is way easier to debug • But not all the components are ready for it out of the box and want to see plain JS objects (I had issues with browserHistory I think) • And on a small research-like app you might not see benefits of immutability yet while you might hit the integration obstacles https://twitter.com/AgileArtem
  • 20. Routing and browse and sharable urls import { Router, Route, IndexRoute, browserHistory, useRouterHistory } from 'react- router'; import { routerMiddleware, syncHistoryWithStore, routerReducer, push } from 'react- router-redux'; import createBrowserHistory from 'history/lib/createBrowserHistory'; const queryString = require('query-string'); const history = syncHistoryWithStore(browserHistory, store, {selectLocationState: (state) => { const r = state.getIn(['metadata', 'routing']); return r || '/'; }}); const routedState = state.setIn(['metadata', 'routing'], { locationBeforeTransitions: { pathname: '/', search: searchString, query: {}, hash: '' } }) https://twitter.com/AgileArtem
  • 21. Routing and browse and sharable urls • React Router is okay, browserHistory is okay, storing routing in a storage is okay, but making it work together is tough – Especially if some more middleware is involved: Redux Dev Tools • I used query string as the initial boss that commanded the state that was setting up the routing – Then state updates are changing the browserHistory-specific keys. browserHistory was updating the address bar • And there are WebKit bugs features. You cannot update URL too often • Use my solution if you just want things to work – Yet it’s programming by accident https://twitter.com/AgileArtem
  • 22. Structuring controls for testing • Simple, isolates core part for testability, but I didn’t use much testing in the end – Started from awesome tutorial by a Finn @teropahttp://teropa.info/blog/2015/09/10/full-stack- redux-tutorial.html export class InputBlock extends React.Component { constructor(props) { … export const InputBlockContainer = connect( mapStateToProps, actionCreators )(InputBlock); https://twitter.com/AgileArtem
  • 23. Using template for injecting stuff into the web root var HtmlWebpackPlugin = require('html-webpack-plugin'); … new HtmlWebpackPlugin({ inject: false, template: 'src/web/index.ejs', googleAnalytics: { trackingId: 'UA-76217125-4', pageViewOnLoad: true }, … <% if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %> ga('create', '<%= htmlWebpackPlugin.options.googleAnalytics.trackingId%>', 'auto'); https://twitter.com/AgileArtem
  • 24. Title/Nav bar react-native-navbar • Surprisingly difficult to do in crosplatform way • react-native-navbar works, but don’t expect to fool a maniacal designer https://twitter.com/AgileArtem
  • 25. Portrait-Landscape layouting and *cascading* styles react-native-media-queries • Works, but you may need to track rotation yourself • Not exactly full. E.g. no difference between min-width and min-device-width const baseStyle = { podorozhnikAppView: { flexDirection: 'column', … export const appStyle = createStyles( baseStyle, maxHeight(400, { optionsBlock: { marginTop: 0, … https://twitter.com/AgileArtem
  • 26. Portrait-Landscape layouting and *cascading* styles <View style={appStyle.podorozhnikAppView} onLayout={(e) => { if(this.props.onAppLayout) { this.props.onAppLayout({ width: e.nativeEvent.layout.width, height: e.nativeEvent.layout.height }); https://twitter.com/AgileArtem
  • 27. Autostoring redux data to localStorage import * as storage from 'redux-storage'; import createEngine from 'redux-storage-engine- reactnativeasyncstorage'; import merger from 'redux-storage-merger- immutablejs'; • Just works • Mobile app only implementation • Immutable JS was an issue here. As restoring data was trying to overwrite the model https://twitter.com/AgileArtem
  • 28. WHAT NOT TO FOLLOW https://twitter.com/AgileArtem
  • 29. WebViews on the app side for the web services • I tried one for disqus • Bad idea. Slow, error prone, hard to debug and fix https://twitter.com/AgileArtem
  • 30. A note on testing • I love automated structured testing so much that for Jolla Sailfish OS I baked HelloWorld wizard that includes testing of engine, UI, C++, JavaScript, whatnot. • Started in full testing more in ReactJS/Native and.. • Nearly completely dropped in the end • For the relatively simple UI-intensive project Redux with its DevTools lets you identify and fix issues faster than tests would have prevented them • In a bigger project with collaborators and less core research I’d use auto testing though https://twitter.com/AgileArtem
  • 31. iPad layout • Didn’t work • Seems to be possible, but solution I used results in the iPhone mode https://twitter.com/AgileArtem
  • 32. Same code for React app on the web, iOS, Android • Yes • No • Maybe • You are only going to really benefit from the logic part only • iOS and Android are close enough for sharing almost everything https://twitter.com/AgileArtem
  • 34. Next project: compare medicine or alcohol prices around you. Anybody in? https://twitter.com/AgileArtem
  • 35. Contacts • https://podorozhnik.firebaseapp.com • https://itunes.apple.com/ru/app/podoroznik-kal- kulator/id1107432204 • https://play.google.com/store/apps/details?id=com.art emmarchenko.podorozhnik • https://twitter.com/AgileArtem • http://github.com/amarchen • http://www.codingsubmarine.com • http://www.agilesoftwaredevelopment.com https://twitter.com/AgileArtem