React Native for Web Developers
‘Cause native apps do some things better
--
If you were expecting all things React web at ReactConf this year you might have left disappointed, React Native was launched at ReactConf 2015 but it was almost entirely the focus of the conference in 2016, Facebook is heavily investing in this tool. After 3 months of working with it full time I now understand why, React Native achieves two big things:
First, it brings a lot of modern tooling and features from the web to iOS and Android developers, see An iOS Developer on React Native.
Secondly, it makes Native development on IOS or Android accessible to web developers by using JavaScript as the programming language and containing polyfills for API’s like fetch and a subset of CSS allowing us to use things like Flexbox for layout.
It bridges a divide between mobile developers and web developers that allows those teams to work together much more easily, it brings benefits to people on both sides.
Your First App
Here’s what an app in ReactNative looks like.
This exact same code works on both iOS and Android as we’re not using any platform specific components.
Seeing is Believing
So it seems you can write once, run on iOS and Android in React Native if you don’t want any platform specific components.
If platform specific components are required, you can either completely separate the components, or if the differences are minimal you can put platform switches inside the components themselves. e.g.
Why We Should Care About Native
The web and native apps both have unique offerings, we should learn about The Other Side to understand each platforms strengths so we can make good decisions about what to spend time building. A mobile web app, native apps, a hybrid web app using Cordova, or a mix of all of the above — having many options for how you can build and deliver applications is a good thing.
When these options are discussed there is often a conclusion that the web simply doesn’t cut it on mobile, that native apps always have an edge over a web version, that native apps will always be faster and feel better.
This is false, If you can create the experiences you want to deliver in mobile browsers then there’s compelling reasons to write once run anywhere. You can use Cordova if you want to deliver installable versions too.
The native platforms do offer different experiences than a web app though, so depending on what you want to build the web may not cut it, that’s why web developers should know and care about the native platforms.
The Web Rules
Here are few reasons why I adore the web as a platform:
Write once, run anywhere - The web runs on any device or browser making it accessible to the widest net
Adaptive to device - Responsive design is a core part of the web, one application can adapt to any devices or screen resolution with little effort.
Huge developer base - Easily find developers when you need and learn from a generous sharing community.
No installs - No other platform has as low friction to entry as following a link
Frequent deploys, Instant updates - Push your code to a server and people can use it straight away
View source - Nothing on the web is hidden, learn from others
Mature and capable - The web has been through the trenches, it has a huge number of evolving JavaScript API’s and capabilities
Unified platform - Those separate technologies designed for the web work beautifully together, embed SVG directly in your HTML and style it’s elements with CSS, manipulate it’s properties with JavaScript.
Evergreen browsers - Browsers these days are shipping features all the time, the developer experience of working on the web is always improving.
Native Apps Do Some Things Better
In my short time working with React Native here are some benefits that I see the native platform bringing:
Familiar UI from the OS - Apps that leverage familiar components like Navigators, Toolbars, Drawers and “pull to refresh” are instantly discoverable and you get navigational aids like “swipe to go back” for free. The Web doesn’t offer any high level abstractions for mobile so experiences are always different from one app to the next.
Touch and Gesture recognition - Taps, multi-touch and swipes needs to be baked into the OS to properly understand users intent. The web offers low level touch events but it’s incredibly difficult to correctly translate all of the combinations of taps, touches and timings to users intent accurately, it’s something far better handled by the OS.
Form controls - Components like Picker, Switch and Slider were designed specifically for mobile, HTML forms were designed in a different era of desktop and those types of controls with default styles are clunky and hard to use on mobile. Of course you can make things better by styling them appropriately on mobile but this comes for free on native platforms.
A tiny component library - HTML was built in a time before mobile, and so HTML is bloated for the needs of mobile apps. It turns out you can build a lot of UI’s with View, Text and Image alone.
Native API’s and access to device features - Because apps are installed they fall under a different security model than web apps, this makes native apps inherently more powerful on mobile devices than web apps.
WebView - If none of that convinces you there’s an awesome WebView component for bringing a piece of the web platform into your app, you can think of it as an iframe.
Markup
React Native doesn’t support HTML, at all, outside of the WebView component.
HTML’s many many tags allow for marking up complex content documents, mobile interfaces have far simpler needs. This isn’t an exhaustive list but it should help set the scene as to what components you can expect to be working with.
View for <div>
Text for <span>
Image for <img />
TouchableHighlight for <button>
ScrollView for <div style=”overflow: auto”>
Image also doubles as background-image as it can contain nested components.
Forms
TextInput for <input type=”text|password|email”>
Switch for <input type=”checkbox”>
Picker for <select>
Picker.Item for <option>
SliderIOS for <input type=”range”>
DatePickerIOS for <input type=”date”>
Native Only Components
There are components on these platforms that don’t have equivalents on the web:
Navigator - A router which lets you transition from page to page
ListView - Forever scrolling lists
ActivityIndicatorIOS - A spinner
SegmentedControlIOS - Tabs
RefreshControl - Pull to refresh
TabBarIOS - Toolbar with icons, text, and notification badges
And many more…
Styles
React native let’s us use a familiar subset of css properties to make styling native components simple. Because they are defined in JavaScript it gives us more power than CSS, allowing us to apply dynamic styles at runtime.
Styles are declared as a JavaScript object with camelCased property names:
A solid subset of CSS is supported that achieves most of what you’ll want.
View - width, height, margin, padding, background, border, opacity
Layout - flex, position(absolute, relative) and transform
Text - color, font, lineHeight, textAlign, textShadow
Most of the shorthand properties don’t map across so you need to be explicit with properties like borderWidth and borderColor for example.
Applying Styles
You can apply styles directly as an object or as an array of objects:
Animations
High level components like Navigator give you animated page transitions for free, all custom animations are defined and triggered from JavaScript.
LayoutAnimation - simple layout transitions like height / transform
Animated - fine grained animations
Here’s a simple example that queues up an easeInEaseOut transition before setState to animate the height.
I must say that I’ve really missed the simplicity of CSS animations and transitions, the LayoutAnimation api is pretty simple to work with though and it does make sense pushing the config for these into JavaScript.
Animation has always been tricky with React’s declarative model, more elegant ways to handle animations will emerge in time.
Events
Touchable / TouchableHighlight - Tappable components that can show feedback
PanResponder / Responder - Low level touch support
DeviceEventEmitter - can be thought of as window.addEventListener, lets us capture events like keyboardWillShow and respond appropriately
JavaScript
React Native apps are JavaScript from top to bottom, it’s possible to break out into ObjectiveC or Swift when needed but for the most part you can stay in JavaScript. JSX looks like XML but it’s just JavaScript.
Babel and ES6 are the defaults so you get a proper module system too with import and export which is lovely.
npm
You can use any JavaScript module that doesn’t depend on the DOM.
Want to use Redux for your state or Lodash for utilities? No problem.
React
React brings patterns like declarative reactive views to native development, you don’t need to worry about defining transitions between states or manual DOM updates, the view is always a reflection of the current state.
The simplicity of UI as pure functions is also a huge win.
iOS and Android
There are separate entry points for android and ios apps in React Native, index.android.js and index.ios.js - The two apps aren’t isolated though, they can share components that have the same API’s. View, Text and Image are universal components that work on both platforms.
Debugging
In the iOS Simulator hit Ctrl + Command + z to open up the debugging options to find these familiar faces.
Debug in Chrome
Enable Hot Reloading
Enable LiveReload
Inspector
Limitations
I’ll admit that I’ve really missed the web at times, for the most part that’s just been unfamiliarity with the native components and having to give up on HTML and make do with a tiny subset of CSS.
A lot of “simple” things that have existed on the web forever can’t be done easily in react-native, background-repeat as an example isn’t easy and things like radial-gradient can’t be achieved without low level hacking.
There’s always an escape hatch out into the native environment though so it’s possible to do anything, it just might require a lot of effort if it’s not a core part of React Native yet. That capability will improve with time though.
Also, no support for SVG feels like a kick in the pants.
React Native is great, there’s now a way for web developers to make valuable contributions to iOS and Android apps using what they know from the web. If you want to make experiences that suit the native platforms better there’s now a way.
I’ll leave you with some inspiring quotes from Christopher Chedeau, one of the core contributors to React Native as he shares his love of the project.