How to Build a Web App with React Native

2019-04-29

The power of React Native as a framework continues to increase over time. For those who are unfamiliar, React Native is a cross-platform framework developed by Facebook. It’s open source and lets you build mobile applications using JavaScript as its core.

Thanks to Nicolas Gallagher’s open source project React Native for Web, now you can use React Native API components to build a web application that uses React DOM as its core. React Native already makes it convenient to write mobile apps for two platforms: iOS and Android. And now the web is slowly entering the picture. 🤩

Sounds interesting, right? In this tutorial, that’s what we’re going to do. We’re going to walk through, step-by-step, the process of integrating a Web App that uses React Native.

Requirements

  • NodeJS version >= 8.x.x and npm/yarn
  • Basic understanding of ES6 JavaScript features, ReactJS, and React Native will be helpful.

Getting Started: Create a React App

To start, go to your terminal and install the following command line tools. The first one will help you scaffold a React app, and the other one will run a React Native app:

1npm install -g create-react-app expo

Note: You might have to use sudo in front of the above command if npm permissions are not set and everything is the default.

After the installation, run the following command from a terminal window in order to generate a new React project:

1create-react-app reactnativeweb-demo

This will generate a new directory. A good thing about this project generating ( official) tool is that it already includes built-in support for aliasing react-native-web to react-native.

The next step is to install a couple more dependencies to make this project work like we want it to. Make sure you traverse inside the newly created project directory and then run the below command:

1yarn add --dev babel-plugin-module-resolver

The babel plugin babel-plugin-module-resolver will help you resolve your project modules when compiling with Babel. React Native uses the Babel compiler internally. Now install the most essential dependencies, without which this project would not run.

1yarn add react-native expo react-native-web

The last step, for now, is to create a file called .babelrc at the root of the project with the following snippet:

1{
2 "plugins": [
3 [
4 "module-resolver",
5 {
6 "alias": {
7 "^react-native$": "react-native-web"
8 }
9 }
10 ]
11 ]
12}

Note: If you want to configure a react-native-web app project where you use your own webpack configuration, or need to write modules with jest, or if you’re a fan of flow, you should take a look at this link in order to make things work properly.

Running on the Web

Before we proceed to build a demo application, let’s see if the current configuration works or not. Open your src/App.js file and replace the content inside it with the following snippet of code:

1import React from 'react'
2import { StyleSheet, Text, View } from 'react-native'
3
4class App extends React.Component {
5 render() {
6 return (
7 <View>
8 <Text style={styles.text}>Hello, world!</Text>
9 </View>
10 )
11 }
12}
13
14const styles = StyleSheet.create({
15 text: {
16 fontWeight: 'bold',
17 fontSize: 30
18 }
19})
20
21export default App

Here, we’re basically using the react-native API build UI components for the web application. Do note that, in React Native terms, View is the equivalent of a div in HTML and text is the equivalent of p or a span. There are a lot of similarities between the APIs of the mobile UI and the Web, but there are important differences to understand and keep in mind.

To run the application, go to a terminal window and write npm start and execute it. In a browser window, on visiting URL http://localhost:3000 you will get the following result.

To verify that it’s building a DOM tree to manage nodes, you can open up developer tools in your web browser and go to inspect > Elements to see the ids and classes with a random string created inside a typical React app.

Similar to a React app, the App component remains the entry point of our application. Also, the index.js file remains unchanged, so it’s very important to note how easy it is to integrate a mobile framework and a web library.

About Styling

React Native relies on JavaScript when it comes to styling component or UI elements. React Native for Web implements the React Native style API. To define a style, it’s the same in a React Native app. All you have to do is declare a StyleSheet object, inside of which each styled property needs to be defined.

In our App.js file, we’re implementing this. Take a look:

1const styles = StyleSheet.create({
2 text: {
3 fontWeight: 'bold',
4 fontSize: 30
5 }
6})

Some of the web units like rem and em are not supported by React Native, so the suggestion here is to avoid using them.

Listing Elements

Rendering a list in React Native Web is similar to React Native for mobile. Let’s add some mockup data and use FlatList container to display the content. Modify App.js as shown below:

1import React from 'react'
2import { StyleSheet, Text, View, FlatList } from 'react-native'
3
4class App extends React.Component {
5 state = {
6 StarWarsAPI: [
7 {
8 id: 1,
9 name: 'Luke Skywalker'
10 },
11 {
12 id: 2,
13 name: 'C-3PO'
14 },
15 {
16 id: 3,
17 name: 'R2-D2'
18 }
19 ]
20 }
21
22 _keyExtractor = (item, index) => item.id
23
24 _renderItem = ({ item }) => (
25 <View style={styles.listContainer}>
26 <Text style={styles.listItem}>{item.name}</Text>
27 </View>
28 )
29
30 render() {
31 return (
32 <View style={styles.container}>
33 <Text style={styles.text}>Hello, world!</Text>
34 <FlatList
35 data={this.state.StarWarsAPI}
36 keyExtractor={this._keyExtractor}
37 renderItem={this._renderItem}
38 />
39 </View>
40 )
41 }
42}
43
44const styles = StyleSheet.create({
45 container: {
46 padding: 10,
47 flex: 1
48 },
49 text: {
50 fontWeight: 'bold',
51 fontSize: 30
52 },
53 listContainer: {
54 paddingTop: 20
55 },
56 listItem: {
57 fontSize: 20
58 }
59})
60
61export default App

If you run it in the browser, you’ll get the following result.

Conclusion

So far, you’ve got the hang of the React Native for Web module. You learned how to integrate React Native as a component API and make it run in a web browser. React Native for Web does not support every React Native component API. It lacks support for Modal, WebView, Slider. Also some modules like CameraRoll and ImageStore are not completely supported, which is understandable but might be helpful if available in some use cases.

Individuals and companies who love to work with React Native are working to close the gap between the web and the framework itself. This will allow building multi-platform applications. Organizations like Expo are currently working on their own fork of React Native Web that might support many more APIs and components than React Native for Web, so the future seems bright in that sense. They will be releasing Expo web with Expo SDK 33.x.x, so look out for that.

Some other resources worth looking at:

All the code used in this tutorial can be found in the GitHub repository below.

amandeepmittal/reactnativeweb-demo

Originally published at Heartbeat

I'm Aman working as an independent fullstack developer with technologies such as Node.js, ReactJS, and React Native. I try to document and write tutorials to help JavaScript, Web and Mobile developers.