Henry Moulton

Scrappy Notes on Chain React 2018 Videos

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.

Simply React by Kent C. Dodds

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:

  • Bundle Size/Perf
  • Maintenance Overhead
  • Implementation Complexity can introduce bugs
  • API Complexity

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

All Together Now by TC Davis

How will React Native become the standard way to ship apps?

Well, how do platforms succeed generally?

People pick the BEST technology:

  • That they can figure out how to use
  • That they can hire for
  • That fits their organisational culture

Let’s look at Java:

  • Hadoop
  • Lucene
  • Kafka
  • Android
  • Clojure

Those things were created probably because Java has:

  • Good Ideas (Run anywhere, Memory management, Object Oriented)
  • Good Marketing
  • Good Libraries
  • Industry Adoption
  • Educational Adoption

Applied to React Native:

  • Good Ideas (Run anywhere, v = f(state))
  • Good Marketing internally, but we need to be better with native developers

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:

  • Flow
  • TypeScript
  • Reason

Navigation:

  • React Navigation
  • React Native Navigation
  • React Native Router

State Management:

  • Redux
  • MobX
  • Rematch

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.

Debugging and Beyond with Reactotron by Darin Wilson

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.

From Sketch to Code: Designing a Component Kit by Samantha Bretous

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.

Detox: Building an E2E Testing Library for React Native by Rotem Mizrachi-Meidan

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.

Learning React Native as a Junior Engineer by Erin Fox

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.

How TypeScript Ruined My Life (In a Good Way) by Andy Mockler

Senior Front End Developer at Shopify, works at Merchant Analytics platform.

Why use types?

  • Encourages API-driven development, always seeing the worst case for your API. You become careful with constructing Interfaces.
  • Self-documenting
  • Let the computer keep track of context, maybe not so important when you’re a 1 or 2 person development, but useful as development team scales

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:

  • Types are written by humans, and while should be assumed truthful could be wrong
  • Avoid ‘any’
  • Andy’s opinion: steer clear of type inheritance, avoid clever types

React Native at Eaze - Marijuana Delivered by Erica Cooksey

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:

  • Still need native libraries and difficult to maintain multiple repos
  • Stack traces are difficult to understand

Facebook is working on a large scale rearchitecture of a synchronous bridge.

Customize Your Boilerplate to Speed Up Development with Ignite by Adrien Thiery

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.

Good Enough Still Isn’t Good Enough by Jani Eväkallio

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

Using SVG in React Native by Ori Harel

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.

Strategies For Using React Native In A Brownfield App by Harry Tormey

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.

GraphQL State Management for React Native by Peggy Rayzis

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.

Unified state management

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

Cache persistence

  • Persist data when app moves to the background
  • Swappable with any storage provider
  • Set maxSize to avoid AsyncStorage limit on Android
import {
    persistCache
} from 'apollo-cache-persist

const cache = new InMemoryCache()

persistCache({
    cache,
    storage: AsyncStorage,
    trigger: 'background'
})

Client Schema

Coming soon.

  • Opt-in schema validation at development time
  • The logic for executing resolvers will be decoupled from your schema to avoid increasing bundle size in production

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.

Tooling

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.

Conclusion

I’m hyped looking forward to using it when it reaches Apollo Core. GraphQL still requires total engineering buyin.

The State of React Native by Ram N

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 Thursday.


I'm Henry Moulton, a software design and development freelancer living in London, UK.

My portfolio will be online soon.

I'm on Twitter and LinkedIn, and for years I've been collecting bits of the internet I found interesting on Tumblr.

You can also signup to have every post I write sent straight to your inbox: