Adam Terlson
Software Engineer
Adam Terlson
@adamterlson
Me
Lead Engineer @ InterNations
ASP
ASP.NET
.NET MVC + FE
Node + FE
FE
👶
Global social network for expats
Events/activities
3 million users
100 employees
MISSION:
SLAY THE HYBRIDS
Objectives:
3 FE
2 BE
Me
solid code
Write
Fewer keystrokes
Style consistency
Error prevention
is
CRITICAL
GOOD
Prevents many classes of errors
Significantly reduces refactoring effort
BAD
Library types are missing or outdated
Error reporting is bad (but somewhat consistent)
Doesn't play well with Saga
Issues are slow to get fixed
TRY - Flow's spread annotation (instead of union)
https://github.com/facebook/flow/issues/1326
FAIL - Eslint doesn't support the syntax
https://github.com/babel/babel-eslint/issues/443
WORKAROUND - Flow's comment syntax
FAIL - Prettier strips the comments
https://github.com/prettier/prettier/issues/204
&
Jenkins
Code Push
Fastlane
State of JS - 2017 Survey Results
Standard, most popular solution
Lots of tooling, libraries
Functional in style
Rather boring
case "MESSAGE_RECEIVE":
return {
ids: idsInsert(state.ids, action.payload),
byId: byIdInsert(state.byId, action.payload),
byConversationId: byIndexInsert(
state.byConversationId,
action.payload,
(message: TMessage) => message.converationId,
),
}
UI Presentation
Stateless Functions that compute visible things:
View, Text, Styles, Animation, Static Text
No business logic!
Documented in Storybook
Not unit tested (shhh)
UI Behavior
compose( connect(mapConversationList), data({ onMount: apiActions.reqConversations, }), pagination('conversations', { limit: 10, onLoadNextPage: apiActions.reqConversations, }), )
(props: ConnectProps & PaginationProps) => (
<FlexView> <SwipeableList data={props.conversations} onSwipe={props.onSwipe} renderItem={renderItem} onEndReached={props.onLoadNextPage} /> <FloatingButton onPress={props.onCreateMessagePress} /> </FlexView> )
navigation is
React Native Navigation
React Navigation
Navigator experimental
React Router Flux
Navigator
Navigator iOS
/app
/ui
/presentational
/layouts
/navigation
import ... from 'react-native-navigation'
Powerful
Expressive
Awesome
Mobile
Modules named by side effect source
Saga dedicated actions
use
Redux Saga Test Plan
Model
import saga, { sagaMiddleware } from 'app/saga' import makeStore from 'app/store' import ui from 'app/ui' const store = makeStore(sagaMiddleware) sagaMiddleware.run(saga) const app = ui(store) export default app
– User
RCTFatalException: Unhandled JS Exception: TypeError: undefined is not an object (evaluating 'e.id') This error is located at: in t in t in t in t in Unknown in n in Connect(n)
export default function withFoo(Component) {
function WithFoo(props) {
// TODO: do something special here.
return <Component {...this.props} />;
}
WithFoo.displayName = `withFoo(${Component.displayName || Component.name}`;
return WithFoo;
}
Source: https://github.com/airbnb/javascript/issues/968
Use React Native Debugger
But....
Debugging API calls in Chrome
– Android User
Scaling
Login
Hybrid
React Native
Experimentation Framework
*
so?
Native Mobile App Challenges | RN Ecosystem Solutions |
---|---|
UI | React Native |
Business Logic & Side Effects | Redux Saga |
State Management | Redux |
Tests | Jest, Calabash, Detox |
Types | Jest & TypeScript |
Code Quality | Eslint, Prettier |
Debugging | React Native Debugger |
Continuous Delivery & Deployments | Code Push, Fastlane, Jenkins |
Performance optimization | Android-first |
Production Monitoring | MS App Center |
Scaling | 😜 |
Library | Usage | Do you care? |
---|---|---|
prettier | developer efficiency | ⭐️⭐️⭐️⭐️ |
eslint | stability | ⭐️⭐️⭐️⭐️ |
redux | state management, action-based infra | ⭐️⭐️⭐️ |
flow | stability | ⭐️⭐️⭐️ |
redux-saga | side effects/bus. logic | ⭐️⭐️ |
reselect, batched subscribe | render cost reduction | ⭐️⭐️ |
fastlane | sane builds | ⭐️ |
code push | continuous delivery | ⭐️ |
app center | crash analytics | ⭐️ |
calabash, detox | acceptance tests | ⭐️ |
⭐️ ⭐️ ⭐️ ⭐️ ⭐️
Adam Terlson
@adamterlson (twitter, github)
slides.com/adamterlson
By Adam Terlson