In this article, we will learn how to make a React Native application with Expo and create-react-native-app and learn about some of the differences between React and React Native code and file structure.

Thinking about making a phone app? Know React and would rather not spend valuable time learning another language? Well, excellent news! React Native is here to save us that time. It also gives us easy access to the phone’s API so we can tap into a phone’s contacts, notifications, camera, and even the gyroscope!

Facebook Guide

If you are looking for the quickest way to “Get Started” with React Native, then look no further than Facebook’s own Getting Started Guide.

First, we need to install create-react-native-app globally:

$ npm install -g create-react-native-app

Then we create our first project:

$ create-react-native-app AlligatorProject $ cd AlligatorProject $ npm start

Once we run npm start , we can look at the output from the command line for more details on how we can run the app in a simulator or install the Expo app on our phone and run it there.

Then the code starting from the generated app itself tells us what to do next:

App.js

import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; export default class App extends React.Component { render() { return ( <View style={styles.container}> <Text> Open up App.js to start working on your app! </Text> <Text>Changes you make will automatically reload.</Text> <Text>Shake your phone to open the developer menu.</Text> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });

* Note that the above code snippet is taken from the Create React Native App project, licensed under BSD 3-Clause “New” or “Revised” License and is copyright 2017 by Create React Native App Contributors. You can find a copy of the license here.

Making an App

Okay, we have “hello world”ed, but where do we go from here? First, let’s change our app to have only one Text field:

App.js (partial)

<Text>Welcome to our app!</Text>

Notice that this change will immediately update our simulator or phone. We may have seen hot reloading for a React web project, but how do we get it for a native app? If we run the npm start command inside a create-react-native-app project, we’ll see something like:

Your app is now running at URL: exp://192.168.1.171:19000

Notice that Expo is just running a web server on port 19000, much like a web app might run on http://192.168.1.171:80 . This is one way that Expo makes the learning curve from React.js into React Native much smoother. But what exactly is Expo?

Introducing Expo

According to the Expo team:

Expo is a free and open source toolchain built around React Native to help you build native iOS and Android projects using JavaScript and React.

So basically, we can get the best of both worlds.

While we’re testing, we can take advantage of an environment that is almost identical to a React.js development environment.

Through the Expo SDK, we can tap into the phone the same way we would with Android or iOS code.

As we continue to develop, we may run into Expo’s limitations. Namely, it currently does not support Bluetooth integration or any third party plugins that are built with native iOS or Android code. All third-party tools in an Expo project must have been built in the Expo environment.

But don’t fret! If we reach one of these limitations, Expo comes with the following command:

$ npm run eject

Ejecting will convert our project into a “pure” React Native project, meaning every time the project is built from now on, it is converted into iOS (Objective C) and/or Android (Java) code. This allows us to get around the limitations of Expo mentioned above, but can make testing and deployment considerably harder. That is, no more auto-generated QR codes or links.

Note that ejecting is a permanent action, so it is a good idea for us to do two things:

Continue to live in the blissfully simple world of Expo until we hit a wall. We can eject our app whenever we want. Make sure a project is saved in version control somewhere before we eject. That way we can go back whenever we want, too.

Digging Deeper

So far, we have covered the main differences between the React.js and React Native development environments. Next, we will cover some of the main differences in the code .

Let’s dive deeper into the React Native code created for us with create-react-native-app and how it differs from React.js code.

What create-react-native-app Gave Us

If we look in the directory created by create-react-native-app , we see the following files:

.babelrc defines how our JSX will be converted to JS.

defines how our JSX will be converted to JS. .gitignore ignores all files in version control that should be unique to each development machine.

ignores all files in version control that should be unique to each development machine. .watchmanconfig defines how files should be watched for changes.

defines how files should be watched for changes. App.js is the center of our project, similar to the root component in React.js.

is the center of our project, similar to the root component in React.js. app.json configures parts of our app that don’t belong in code.

configures parts of our app that don’t belong in code. App.test.js is the testing center of our project, and comes with a free test so we can get TDD started right away.

is the testing center of our project, and comes with a free test so we can get TDD started right away. package.json and package-lock.json define a basic set of packages and scripts to get us up and running.

and define a basic set of packages and scripts to get us up and running. README.md provides a wealth of detail on troubleshooting, deploying, updating, and more.

Our App

After our update, our code should look like this:

App.js

import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; export default class App extends React.Component { render() { return ( <View style={styles.container} > Welcome to our app! </View> ); } } const styles = StyleSheet.create ({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });

React Native Code Differences

Looking at our app, we see a lot of code that is similar to React.js. From top to bottom, we see:

ES6 import s

s object destructuring

Exported class that extends the React Component

render() function that returns JSX

function that returns JSX const variable assignment

So far, so good. But there are also some new things:

Text and View are not HTML tags. This is because a React Native app is not a webpage. All tags in React Native must be a React Native component. So no more <div> s or <form> s.

and are not HTML tags. This is because a React Native app is not a webpage. All tags in React Native must be a React Native component. So no more s or s. No more className or CSS imports. Again, this is because a React Native app is not a webpage. This requires some rethinking if we are used to React.js apps, where we can take advantage of classes, ids, media queries, and more from CSS, Less, or Sass. The good news, though, is that the React Native StyleSheet object allows us to use the full weight of ES6: things like variables, arrow functions, for loops, and ternaries.

In a nutshell, these two major differences illustrate the crux of React.js vs React Native code confusion.

For example, if we are used to this from React.js:

<img src="myPic.gif" />

In React Native, that would look like this:

<Image source="myPic.gif" />

Also we have to import that Image component from React Native. Not incredibly different, but when we’re switching between React.js and React Native, those subtle differences can lead to some frustrating errors.

There is a third difference that will appear once our apps get more complex: many of the npm packages we import for React.js will not work with React Native. If we are using a pure Javascript npm package we can use it both in React.js and React Native, but once we involve HTML or CSS (e.g. reactstrap or any form validation libraries) we will need to look for a React-Native-compatible alternative.

Conclusion

Expo and create-react-native-app allow us to utilize a React Native development environment that is very similar to React.js, but also allow us to take advantage of native mobile device features.

In a nutshell, the three main differences between React.js and React Native are:

No more HTML

No more CSS

Any React.js npm packages that rely on HTML or CSS will not work with React Native

With React Native, we have to sacrifice some of our comfortable tools from pure web development, but there are some powerful tools we get in exchange which make the move to React Native well worth it.

Stay tuned for more Alligator.io articles on putting our app in the App Store, adding native camera integration, connecting to a phone’s contacts, and push notifications.