In this article written by Eric Masiello and Jacob Friedmann, authors of the book Mastering React Native we will cover:
(For more resources related to this topic, see here.)
I'm hard pressed to think of another topic that developers are more passionate about than their preferred code editor. Of the many options, two popular editors today are GitHub's Atom and Microsoft's Visual Studio Code (not be confused with the Visual Studio 2015). Both are cross-platform editors for Windows, macOS, and Linux that are easily extended with additional features. In this section, I'll detail my personal experience with these tools and where I have found they complement the React Native development experience.
Facebook has created a package for Atom known as Nuclide that provides a first-class development environment for React Native It features a built-in debugger similar to Chrome's DevTools, a React Native Inspector (think the Elements tab in Chrome DevTools), and support for the static type checker Flow.
Download Atom from https://atom.io/ and Nuclide from https://nuclide.io/.
To install the Nuclide package, click on the Atom menu and then on Preferences..., and then select Packages. Search for Nuclide and click on Install. Once installed, you can actually start and stop the React Native Packager directly from Atom (though you need launch the simulator/editor separately) and set breakpoints in Atom itself rather than using Chrome's DevTools. Take a look at the following screenshot:
If you plan to use Flow, Nuclide will identify errors and display them inline. Take the following example, I've annotated the function timesTen such that it expects a number as a parameter it should return a number. However, you can see that there's some errors in the usage. Refer to the following code snippet:
/* @flow */
function timesTen(x: number): number {
var result = x * 10;
return 'I am not a number';
}
timesTen("Hello, world!");
Thankfully, the Flow integration will call out these errors in Atom for you. Refer to the following screenshot:
Flow integration of Nuclide exposes two other useful features. You'll see annotated auto completion as you type. And, if you hold the Command key and click on variable or function name, Nuclide will jump straight to the source definition, even if it’s defined in a separate file. Refer to the following screenshot:
Visual Studio Code Visual Studio Code is a first class editor for JavaScript authors. Out of the box, it's packaged with a built in debugger that can be used to debug Node applications. Additionally, VS Code comes with an integrated Terminal and a git tool that nicely shows visual diffs.
Download Visual Studio Code from https://code.visualstudio.com/.
The React Native Tools extensions for VS Code add some useful capabilities to the editor. For starters, you'll be able to execute the React Native: Run-iOS and React Native: Run Android commands directly from VS Code without needing to reach for terminal, as shown in the following screenshot:
And, while a bit more involved than Atom to configure, you can use VS Code as a React Native debugger. Take a look at the following screenshot:
The React Native Tools extension also provides IntelliSense for much of the React Native API, as shown in the following screenshot:
When reading through the VS Code documentation, I found it (unsurprisingly) more catered toward Windows users. So, if Windows is your thing, you may feel more at home with VS Code. As a macOS user, I slightly prefer Atom/Nuclide over VS Code. VS Code comes with more useful features out of the box but that easily be addressed by installing a few Atom packages. Plus, I found the Flow support with Nuclide really useful. But don't let me dissuade you from VS Code. Both are solid editors with great React Native support. And they're both free so no harm in trying both.
Before totally switching gears, there is one more editor worth mentioning. Deco is an Integrated Development Environment (IDE) built specifically for React Native development. Standing up a new React Native project is super quick since Deco keeps a local copy of everything you'd get when running react-native in it. Deco also makes creating new stateful and stateless components super easy.
Download Deco from https://www.decosoftware.com/.
Once you create a new component using Deco, it gives you a nicely prefilled template including a place to add propTypes and defaultProps (something I often forget to do). Refer to the following screenshot:
From there, you can drag and drop components from the sidebar directly into your code. Deco will auto-populate many of the props for you as well as add the necessary import statements. Take a look at the following code snippet:
<Image
style={{
width: 300,
height: 200,
}}
resizeMode={"contain"}
source={{uri:'https://unsplash.it/600/400/?random'}}/>
The other nice feature Deco adds is the ability to easily launch your app from the toolbar in any installed iOS simulator or Android AVD. You don't even need to first manually open the AVD, Deco will do it all for you. Refer to the following screenshot:
Currently, creating a new project with Deco starts you off with an outdated version of React Native (version 0.27.2 as of this writing). If you're not concerned with using the latest version, Deco is a great way to get a React Native app up quickly. However, if you require more advanced tooling, I suggest you look at Atom with Nuclide or Visual Studio Code with the React Native Tools extension.
The development experience is one of the most highly touted features by React Native proponents. But as we well know by now, React Native is more than just a great development experience. It's also about building cross-platform applications with a common language and, often times, reusable code and components. Out of the box, the Facebook team has provided tremendous support for iOS and Android. And thanks to the community, React Native has expanded to other promising platforms. In this section, I'll take you through a few of these React Native projects. I won't go into great technical depth, but I'll provide a high-level overview and how to get each running.
Introducing React Native Web React Native Web is an interesting one. It treats many of React Native components you've learned about, such as View, Text, and TextInput, as higher level abstractions that map to HTML elements, such as div, span, and input, thus allowing you to build a web app that runs in a browser from your React Native code. Now if you're like me, your initial reaction might be—But why? We already have React for the web. It's called... React! However, where React Native Web shines over React is in its ability to share components between your mobile app and the web because you're still working with the same basic React Native APIs.
Learn more about React Native Web at https://github.com/necolas/react-native-web.
React Native Web can be installed into your existing React Native project just like any other npm dependency:
npm install --save react react-native-web
Depending on the version of React Native and React Native Web you've installed, you may encounter conflicting peer dependencies of React. This may require manually adjusting which version of React Native or React Native Web is installed. Sometimes, just deleting the node_modules folder and rerunning npm install does the trick.
From there, you'll need some additional tools to build the web bundle. In this example, we'll use webpack and some related tooling:
npm install webpack babel-loader babel-preset-react babel-preset-es2015 babel-preset-stage-1 webpack-validator webpack-merge --save
npm install webpack-dev-server --save-dev
Next, create a webpack.config.js in the root of the project:
const webpack = require('webpack');
const validator = require('webpack-validator');
const merge = require('webpack-merge');
const target = process.env.npm_lifecycle_event;
let config = {};
const commonConfig = {
entry: {
main: './index.web.js'
},
output: {
filename: 'app.js'
},
resolve: {
alias: {
'react-native': 'react-native-web'
}
},
module: {
loaders: [
{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
}
]
}
};
switch(target) {
case 'web:prod':
config = merge(commonConfig, {
devtool: 'source-map',
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
});
break;
default:
config = merge(commonConfig, {
devtool: 'eval-source-map'
});
break;
}
module.exports = validator(config);
Add the followingtwo entries to thescriptssection ofpackage.json:
"web:dev": "webpack-dev-server --inline --hot",
"web:prod": "webpack -p"
Next, create an index.htmlfile in the root of the project:
<!DOCTYPE html>
<html>
<head>
<title>RNNYT</title>
<meta charset="utf-8" />
<meta content="initial-scale=1,width=device-width" name="viewport" />
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="/app.js"></script>
</body>
</html>
And, finally, add an index.web.jsfile to the root of the project:
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
AppRegistry
} from 'react-native';
class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>Hello World!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#efefef',
alignItems: 'center',
justifyContent: 'center'
},
text: {
fontSize: 18
}
});
AppRegistry.registerComponent('RNNYT', () => App);
AppRegistry.runApplication('RNNYT', { rootTag: document.getElementById('app') });
To run the development build, we'll run webpackdev server by executing the following command:
npm run web:dev
web:prod can be substituted to create a production ready build.
While developing, you can add React Native Web specific code much like you can with iOS and Android by using Platform.OS === 'web' or by creating custom *.web.js components.
React Native Web still feels pretty early days. Not every component and API is supported, and the HTML that's generated looks a bit rough for my tastes. While developing with React Native Web, I think it helps to keep the right mindset. That is, think of this as I'm building a React Native mobile app, not a website. Otherwise, you may find yourself reaching for web-specific solutions that aren't appropriate for the technology.
Announced at the Facebook F8 conference in April, 2016,the React Native plugin for Universal Windows Platform (UWP)lets you author React Native apps for Windows 10, desktop Windows 10 mobile, and Xbox One.
Learn more about React Native plugin for UWP at https://github.com/ReactWindows/react-native-windows.
You'll need to be running Windows 10 in order to build UWP apps. You'll also need to follow the React Native documentation for configuring your Windows environment for building React Native apps. If you're not concerned with building Android on Windows, you can skip installing Android Studio. The plugin itself also has a few additional requirements. You'll need to be running at least npm 3.x and to install Visual Studio 2015 Community (not be confused with Visual Studio Code). Thankfully, the Community version is free to use. The UWP plugin docs also tell you to install the Windows 10 SDK Build 10586. However, I found it's easier to do that from within Visual Studio once we've created the app so that we can save that part for later.
I won't walk you through every step of the installation. The UWP plugin docs detail the process well enough. Once you've satisfied the requirements, start by creating a new React Native project as normal:
react-native init RNWindows
cd RNWindows
Next, install and initialize the UWP plugin:
npm install --save-dev rnpm-plugin-windows
react-native windows
Running react-native windows will actually create a windows directory inside your project containing a Visual Studio solution file. If this is your first time installing the plugin, I recommend opening the solution (.sln) file with Visual Studio 2015. Visual Studio will then ask you to download several dependencies including the latest Windows 10 SDK. Once Visual Studio has installed all the dependencies, you can run the app either from within Visual Studio or by running the following command:
react-native run-windows
Take a look at the following screenshot:
Much as the name implies, React Native allows you to create macOS desktop applications using React Native. This project works a little differently than the React Native Web and the React Native plugin for UWP. As best I can tell, since React Native macOS requires its own custom CLI for creating and packaging applications, you are not able to build a macOS and mobile app from the same project.
Learn more about React Native macOS at https://github.com/ptmt/react-native-macos.
Much like you did with the React Native CLI, begin by installing the custom CLI globally by using the following command:
npm install react-native-macos-cli -g
Then, use it to create a new React Native macOS app by running the following command:
react-native-macos init RNDesktopApp
cd RNDesktopApp
This will set you up with all required dependencies along with an entry point file, index.macos.js. There is no CLI command to spin up the app, so you'll need to open the Xcode project and manually run it. Run the following command:
open macos/RNDesktopApp.xcodeproj
The documentation is pretty limited, but there is a nice UIExplorer app that can be downloaded and run to give you a good feel for what's available. While on some level it's unfortunate your macOS app cannot live alongside your iOS and Android code, I cannot think of a use case that would call for such a thing. That said, I was delighted with how easy it was to get this project up and running.
I think it's fair to say that React Native is moving quickly. With a new version released roughly every two weeks, I've lost count of how many versions have passed by in the course of writing this book. I'm willing to bet React Native has probably bumped a version or two from the time you started reading this book until now. So, as much as I'd love to wrap up by saying you now know everything possible about React Native, sadly that isn't the case.
Let me leave you with a few valuable resources to continue your journey of learning and building apps with React Native: