React.js Conf: The Good Parts

I had the amazing opportunity to attend React.js conf in San Fransisco on 22nd/23rd of February thanks to a generous diversity scholarship from Facebook! Two full days of talks from the creators, contributors and users of React.js, and 600+ React enthusiasts from around the world there to take it all in. It was a great chance to meet other React-ers and share ideas in a place where it is completely acceptable to take your laptop out at breakfast or the bar and talk shamelessly about code.

From what I heard, tickets this year were incredibly hard to get and if you didn’t have time to watch the live stream, here’s my summary of ‘React.js Conf: The Good Parts’ and a plethora of links for cool resources I heard about from the talks and talking to other people.

Nick Schrock’s Keynote really set the tone for the conference, highlighting how React has grown from a JavaScript library into its own ecosystem that can fundamentally advance web development and React Native is completely changing the way mobile apps are being built, with cross-stack engineers replacing platform specific roles and teams. He also pointed out some pretty impressive figures — like the fact that the Facebook Ads manager and Groups iOS and Android apps share 85–90% of their React Native code and were built with a single team! Many of the features on the Facebook app are also already in React Native, one being the Facebook Friend’s day video which you might have seen a couple of weeks ago!

Ben Alpert’s talk on ‘Making great React Apps’ touched on several ideas of what still needed to be improved in React and React Native including animations, gestures, rendering fast lists and tools for improving developer experience across React and React Native — like what if you could remove the need for setting up webpack/babel to quickly prototype a new project with just one file e.g. create app.js and just call ‘react run platform=ios’?

The announcement of Draft.js, a rich text editing library for React from Facebook, got everyone pretty excited! Making input text bold, cut, copy, paste, adding custom transformations like the ‘mentions/check-ins’ that can be added for statuses on Facebook — Draft.js makes this all infinitely easier for your React Apps. Isaac Salier-Hellendang’s talk explained how the library takes the good parts of the ‘contentEditable’ browser feature (native cursor and selection behaviour, native input events & key events, all rich text features, automatic autogrowing of elements, accessibility and that it works in all browsers) and applies the principles of React to turn it into a controlled component — like a Text Input field with an onChange event handler and the input value saved to a state. I definitely recommend watching the full talk if you’re interested in the implementation details.

Data handling in React applications was a recurring theme throughout the two days with multiple talks highlighting the many different options out there. Lin Clark’s talk illustrated with her quirky code-cartoons made for a fun and extremely clear introduction to Flux, Redux and Relay.

In short, Flux is out, Relay is a bit too complicated to start with and Redux wins.

But seriously, Redux cuts some of the complexity of flux by using functional composition instead of callback registration, has a single store with immutable state, is super declarative, is great for testing and makes hot reloading and time travel debugging possible. Relay on the other hand requires a GraphQL server which is a beast in itself and takes a lot more set up, but has the additional benefits of being able to handle caching, query optimisation and network errors and the readability that comes from co-location of queries and views. Relay also allows deferred queries (e.g. retrieval of the title and text of an article and comments later) and reduction in the the size of queries — relay retrieves data and puts it in a local cache so some query data can just be retrieved from the cache. Jared Forsyth’s talk introduced Re-frame and Om/next, both ClojureScript libraries. Re-frame is like Redux but uses subscriptions to define how to get data from state, which can be memoized so subscriptions are reused between components and for those of you familiar with Redux, there’s no need to do mapStateToProps(state){} in the container. Om/next is a Relay like library but without the need for a GraphQL server.

Optimisation and performance improvement were also mentioned repeatedly. Aditya Punjani’s talk about optimising the FlipKart mobile website for 2G connections in India introduced two really interesting ideas: the App Shell architecture instead of traditional server-side rendering (breaking down the app into loading state, with placeholders for data and loaded state, with the loading state being displayed in the first paint of the page) and service workers, a very cool browser API which can be used to intercepts all network requests so you can choose to either retrieve data from cache (for offline use) or from the network.

Bhuwan Khattar suggested some methods for speeding up start up time. Branches in code — e.g. when a/b testing can lead to slow start up times as all the modules for each branch need to be downloaded leading to lots of unneccessary overhead. This is difficult to optimise because the branch chosen might be dependent on runtime data. One of the solutions he suggested was inline requires for lazy execution — i.e. only require things when they are necessary rather than requiring all the modules at the top of the file. Bhuwan also suggested using a helper function ‘matchRoute’ which does pattern matching based on the route name and only conditionally downloads and executes the code for each route. The example code below is from this great article by Jan Pojer about routing (specifically with Relay and react-router).

Another solution used by Facebook is to use a wrapper instead of ‘require’ — use the wrapper to require dependencies that are not needed on initial render — these are downloaded as necessary with a loading indicator being shown in the meantime.

In Tadeu Zagallo’s talk on ‘Optimising React Native’ he showed how to profile apps using the simulator in Xcode — bring up the developer menu inside the simulator (Cmd-Z) and click ‘start profiling’ and then view in chrome. This brings up a handy menu in Chrome so you can see which functions take the longest to run. He also mentioned two things to remember: always add component keys for lists — React’s DOM diffing algorithm uses the keys to check which items need re-rendering so add keys to make sure all the list items are not re-rendered and try to always use the ‘shouldComponentUpdate’ lifecycle method to prevent re-render unless necessary.

One of the most exciting things for me was hearing about the new Navigation API in React-Native from Eric Vicenti. After struggling with the Navigator component for months, the new declarative version sounds like a much better solution, borrowing heavily from Redux to remove the state from within the component and using actions for transitioning between views. The new changes should also support deep linking with URIS, a feature thats highly desirable in mobile apps. I still haven’t had a look at the new version properly but it’s now available as ‘NavigationExperimental’ in the latest release of React Native.

Leland Richardson’s talk about testing React Native was also super exciting! Not only has he created a library ‘Enzyme’ to help with traversing the DOM tree when shallow rendering React, he’s only just gone and created a complete mock of the entire React Native API! Enzyme has shallow, mount and render methods as well as methods to find nodes of a specifc type in the tree. And he’s also created some handy examples of how to use both libraries (links at the end)!

Jamison Dance’s talk has really made me want to try the Elm language! I’d only ever heard of Elm so it was completely new to me but in short, Elm is a functional programming language that transpiles to JavaScript and runs in the browser. It has a static type system (so no run time errors!) and there’s no ‘null’!. Elm only has stateless functions and only immutable data. Jamison showed how Elm applications have a similar tree architecture to React apps with parent components passing data down to child components which then respond to user interactions by sending data back to their parents which then update the top level app state and cause the App to re-render. Updating of state in React can be done in a number of ways including different libraries discussed earlier like Redux or Flux, but in Elm there’s a built in system for updating state using Observables. The tradeoff is between constraints and guidelines — if you trust the language designers to have made good decisions for you, it eliminates the need to try and decide between different libraries for your application and you can focus on the problems specific to your application domain. Jamison suggested that learning Elm could help you become a better React Developer and I think I’m going to give it a go!

There were also some cool tips/ideas from the lightning talks:
* A way of making React Native code more reusable between iOS and Android — create a wrapper for components that uses Platform.OS to check the operating system
* Nuclide IDE support for react-native to make the developer experience just like the web. There’s now a react-native-debugger, react-native-inspector and the ability to add breakpoints!
* React Native for web! A way to build truly platform agnostic code, enable universal rendering and it comes with built in web accesibility!

And then there were some of the wackier talks on Virtual Reality , Open-GL effects and making an arduino-raspberry-pi-React powered version of Jeopardy!!

Overall the conference was an amazing experience and my list of ‘new things to learn’ has now grown completely out of hand!

Links

Libraries/APIs

For React:
* Draft.js — Rich Text Editing with React
* Email templating using React — Oy-Vey
* Gatsbyjs static site generator using React + Markdown
* Open GL for React!
 * gl-react
 * gl-react-dom
 * gl-react-inspector
 * GL Sandbox
* Falcor — Data fetching library by Netflix
* Cycle.js — data flow architecture based on observables
* Enzyme — JavaScript Testing utility for React that mimicks jQuery’s API for DOM traversal
* Guide for using Enzyme with Webpack

For React Native
* NavigationExperimental — new declarative Navigator API
* Cordova plugins for React Native
* Open GL for React Native — gl-react-native
* React Native Web
* A complete mock of React Native
* Guide for testing React Native with Enzyme
 * Example React Native tests with Enzyme

Random…
* Service Workers to support offline experiences, push notifications and loads more
* Push Notifications using Google Cloud Messaging
* Chrome api for speech recognition
* Webpack plugin to install modules from ‘import’ statements (thanks Eric Clemmons!)
* API Archive of Jeopardy Questions!!
* Track.js — Monitor and report JS errors in web applications
* Raygun.io — Crash reporting

Developer Tools

* React Native plugin for Visual Studio Code
* Deco IDE for React Native
* Nuclide with React Native including react-native-debugger, ability to add breakpoints and react native inspector, flow support
* HockeyApp — distribute beta versions of apps without using the app store

Explanations/Tutorials

https://github.com/nikhilaravi/reactconf2016