July 17, 2018
Tags: Development
Chain React 2018 was a conference focused on React Native covering a lot of the latest developments in the ecosystem.
Here’s my notes from most of the videos.
There are patterns that have emerged in React that allow you to promote code reuse without sacrificing the simplicity or flexibility of the component. In this talk we’ll cover some of these patterns that will make your React components more useful.
Kent walks through an example of how an Accordian component can explode with complexity by trying to provide an API for all use cases. Kent then explores a different pattern that while introducing some duplication, significantly reduces complexity.
Issues with exploding Component APIs:
Kent introduces a component design pattern that stops a component getting out of control. The clever part is the use of being able to pass multiple state reducers.
class Accordian extends React.Component {
static defaultProps = {
stateReducer: (state, changes) => changes,
onStateChange: () => {
}
}
state = { openIndexes: [0] }
getState(state = this.state) {
return {
openIndexes: this.props.openIndexes === undefined ? state.openIndexes : this.props.openIndexes
}
}
internalSetState(changes, callback = () => {
}) {
let allChanges
this.setState(
state => {
const actualState = this.getState(state)
const changesObject = typeof changes === 'function' ? changes(actualState) : changes
allChanges = this.props.stateReducer(actualState, changesObject)
return allChanges
},
() => {
this.props.onStateChanges(allChanges)
callback()
})
}
handleItemClick = index => {
this.internalSetState(state => {
const closing = state.openIndexes.includes(index)
return {
type: closing ? 'closing' : 'opening',
openIndexes: closing ? state.openIndexes.filter(i => i === index) : [...state.openIndexes.index]
}
})
}
render() {
return this.props.children({
openIndexes: this.getState().openIndexes,
handleItemClick: this.handleItemClick
})
}
}
So AboveAccordian looks like:
function AboveAccordian({items, ...props}) {
return (
<Accordian {...props}>
{({openIndexes, handleItemClick}) => (
<AccordianItem key={item.title}>
<AccordianContents isOpen={openIndexes.includes(index)}>
{item.contents}
</AccordianContents>
<AccordianButton
isOpen={openIndexes.includes(index)}>
{item.title}{' '}
{openIndexes.includes(index) ? '👆' : '👉'}
</AccordianButton>
</AccordianItem>
)
}
</Accordian>
)
}
function LeftAccordian({items, ...props}) {
return (
<Accordian {...props}>
{({openIndexes, handleItemClick}) => (
<AccordianItem key={item.title} variant="horizontal">
<AccordianContents isOpen={openIndexes.includes(index)}>
{item.contents}
</AccordianContents>
<AccordianButton
isOpen={openIndexes.includes(index)}>
{item.title}{' '}
{openIndexes.includes(index) ? '👉' : '👈'}
</AccordianButton>
</AccordianItem>
)
}
</Accordian>
)
}
Want tabs? Use the stateReducer:
(combineReducers and single, preventClose)
function Tabs({ stateReducer, ...props}) {
return (
<Accordian
stateReducer={combineReducers(
stateReducer,
single,
preventClose
)}
{...props}
/>
)
}
Kent highlights that his Downshift library uses the stateReducer prop and is compatible with React Native
How will React Native become the standard way to ship apps?
Well, how do platforms succeed generally?
People pick the BEST technology:
Let’s look at Java:
Those things were created probably because Java has:
Applied to React Native:
People go from Exploration to Selection, React Native is great for exploring (Snack and Expo make it easy) but is it ready for Selecting it as a technology for Production? Have previous mis-steps made it harder?
We have three solutions for every problem.
Static Typing:
Navigation:
State Management:
This isn’t friendly for beginners, coming up with pros and cons lists isn’t easy, but it is necessary.
This talk has similar ties to Jani’s talk - we need a really strong React Native success story.
Seriously cool tool that looks like it could replace/complement React Native Debugger
Facebook is open sourcing a similar tool called Sonar… no date on React Native.
Allows the recording and replay of common actions like Logging in.
Structuring a design system:
Building blocks: Color Palettes, Typographic Scales, Grid Definitions, Icons and Assets
UI Patterns: Templates, Modules, Components, Elements
Rules: Design Principles, Implementation Guidelines, Editorial Guidelines
I feel like this the concept of designing a guideline for developers to use when developing a component kit might become a bit out of date. The release of Framer X and other tools is closing the interface design/development gap.
E2E tests are probably a lot more useful once a product matures and the APIs stabilise. Use Mocked E2E tests. They’re still time consuming to set up, might be better to do QA at some level of complexity.
Storybook makes it easy for Juniors to play with components that have props.
MLS uses GraphQL and it looks great and I need to look more into it.
MLS advocates Pair Programming with Teachable Moments.
Senior Front End Developer at Shopify, works at Merchant Analytics platform.
Why use types?
Examples:
format formatConference(name: string, location: string) {
return `${name} ${location}`
}
Another example:
formatCurrency(amount, options)
What options are required, what are the properties in the options object?
interface Options {
currencyCode: string
includeCents?: boolean
condenseThousands?: boolean
useCurrencyCode: boolean
}
formatCurrency(amount: number, options: Options)
Question marks mean the property is optional
In React:
interface Props {
uri: string,
caption?: string
}
class ArticleImage extends React.Component<Props> {}
Writing Effective TypeScript:
Two apps:
Drivers app, and Consumer app.
Current state: Drive app is a cross platform single repo React Native app
The Consumer iOS app is React Native and the Android app is in Kotlin
Big love of Code push.
The driver app isn’t in the app store, it can’t go in the app store (it delivers weed), so it’s side loaded on a drivers phone.
Downsides of RN for driver app:
Facebook is working on a large scale rearchitecture of a synchronous bridge.
Ignite CLI for React Native made by Infinite Red
CLI to develop faster, just use it.
Boilerplate: Especially applies to agencies, you want tooling, navigation, state management etc.
Gives choices for vector icon library, or animation library?
Followup: Will it support Expo
Generators: Simple commands to generate code, generate components, redux boilerplate and containers
ignite g component DraggableDrawer
Simple to write your own plugins.
Works at Formidable London.
Uses Renaissance art to open his talk and will use them as metaphors for writing React.
Learn once, write everywhere, starting to doubt this representation with respect to React Native.
Cites Building Stellar User Interfaces by Alex Kotliaskyi, 2017 as example of a great talk.
Can we create “Good Enough” apps, but are they good enough? Cites Xamarin Forms, Cordova as examples that aren’t good enough but relies on experience to say that React Native could be good enough.
Skevy is a legend and diassembled the QuartzCore framework to get a better Spring animation.
Facebook has a great engineering team with practically unlimited resources, but React Native still isn’t good enough.
As React Native developers our job is create great User Interfaces. Sweat the little details, caring is cool. Learn the laws that govern user experience. Study the work of masters, copy, steal and study the best.
Define your aesthetic.
“The greatest danger for most of us is not that our aim is too high and we miss it, but that it is too low and we reach it” - Michelangelo
Don’t need to use ART, react-native-svg is included in expo.
Rich documentationa and supports touch events.
Goes through some examples and later goes on to animation.
Goes through interesting case study of of a client who wanted to use React native to power A/B tested subscription up-sell screens and use code push to ship new experiments without submitting a new app to the app store.
What does the example need to do?
Used React Native Event Bridge from Pinterest for Brownfield application.
Goes through code examples of both the JS and Swift code.
Recommends looking at Artsy - they have a series of posts of doing React Native at Artsy and also open sourced their components: Emission.
Engineering Manager at Apollo, previously an engineer on the client side team also doing developer advocacy.
What was the last React Native feature that you built? A form, data picker, cards etc.
How much time was spent on building UI? How much time was spent managing data?
Since React has no opinions about data management and data fetching, it often takes more time doing data management.
Have to learn reducers, selectors, sagas or thunks, action creators, immutability, error handling at a basic level, but at an advanced level have to learn offline, caching, SSR, optimistic UI, realtime, retries, poling, normalisation and pagination.
Our apps are data driven, and we end up duplicating data management logic across clients. GraphQL gets rid of duplication. Can layer an Apollo client instead of doing action creators. Clients can request exactly what they need.
Apollo reduces complexity:
const GET_DOGS = gql`
dogs {
id
breed
displayImage
}
`
const Dogs = () => (
<Query query{GET_DOGS} pollInterval={1000}>
{({ loading, data, error, fetchMore }) => {
if (loading) return null
if (error) reutrn 'Error'
return data.dogs.map(dog =>
<Dog key={dog.id} {...dog} />
)
}}
</Query
)
You get so much for free: normalisation, caching, loading state, error state as well as reactively updating UI.
Greenfield? Apollo Client
Apollo Client intelligently normalises and caches for you. Redux results in using normalisr + writing your own caching.
So far we’ve examined remote data. Apollo can also manage local data, use apollo-link-state. Instead of sending it to GraphQL server you can use Apollo Link to send a request anywhere, local state, Firebase, REST API etc.
The Apollo cache becomes the single source of truth for all local and remote data.
We don’t even need Redux anymore.
40% of React Apollo are also using Apollo Link State, including Hilton, New York Times in production.
Airbnb engineers are also using it in their forms:
export const updateCalendarDateRange = (
_,
{ input: { startsAt, endsAt } },
{ cache },
) => {
const calendarDateRange = {
__typename: 'CalendarDateRange',
startsAt,
endsAt,
}
cache.writeData({ data: { calendarDateRange } })
return null
}
Write to cache using cache.writeData
const GET_CALENDAR = gql`
query GetCalendarDateRange {
calendarDateRange @client {
startsAt
endsAt
}
}
`
Uses @client
directive to tell Apollo Client to use local cache.
Apollo Link State will be part of Apollo Client core soon and will result in easier integration with server rendering and cache persistence. It’ll also be easier to call client resolvers directly from within Mutation components
import {
persistCache
} from 'apollo-cache-persist
const cache = new InMemoryCache()
persistCache({
cache,
storage: AsyncStorage,
trigger: 'background'
})
Coming soon.
Can then upload your schemas to Apollo Engine can see which local fields are requested the most.
Can then integrate with GitHub Checks so can become part of your CI workflow so you could see if you’re changing queries in your app you can get notified if it’s a breaking change. Right now in Redux if you remove an action you don’t know if it’s going to break something.
Apollo Dev Tools currently looking to work with React Native debugger. Ideally want to explore all available local and remote mutations.
Developed Apollo Code Gen to create TypeScript files.
VSCode extension coming soon to run queries.
I’m hyped looking forward to using it when it reaches Apollo Core. GraphQL still requires total engineering buyin.
Front End Developer at Facebook.
Ads Manager app, Analytics app and the companion app are all greenfield apps, Instagram and the main Facebook App uses React Native for a few screens, Marketplace is completely React Native and has 800m+ MAU, more than 100 screens.
Given the scale of working on Marketplace they ran into some interesting problems.
Users expect instant responses, sometimes long lists being scrolled really fast using <FlatList/>
result in white screen.
Ram then goes into a bunch of explanation that actually warrants watching the video, it’s explained really well and it helps by showing the code alongside an animated Virtual DOM Tree.
Thanks for reading! If you have any comments, questions or feedback please get in contact. Have a nice Sunday.
I'm Henry Moulton, a software design and development freelancer living in London, UK.
My portfolio will be online soon.