Creating Live React Native Web Demos

Written by Cody Pearce

Live demos allow developers to preview components without requiring them to go through the manual process of downloading, installing, and displaying each component individually.


While Snack.expo.io is a great service that can render react-native on the web, it can be frustratingly slow and unreliable. Instead, we can render react-native components with react-native-web, and use react-live to allow live editing. React-live loads faster, is more reliable, and allows much more control over both the editor and the component preview.


Set Up React Native Web


To start, clone this simple react-native-web template:
https://github.com/codypearce/react-native-web-simple


    
git clone [email protected]:codypearce/react-native-web-simple.git
cd react-native-web-simple
npm i
npm start
    
  

The app should be running on port 8080. If there are no errors, “Hello World” will be displayed on the page.


Note: The key to running react-native on the web is found in the webpack.config.js file. The code below tells webpack to replace all instances of react-native with react-native-web components.


    
...
**resolve: {
  // auto resolves any react-native import as react-native-web
  alias: {
    "react-native": "react-native-web"
  },
  extensions: [".web.js", ".js"]
},**
...

    
  

You should now be able to add react-native components to App.js. However, not all react-native components are supported yet. All supported components are listed here: https://github.com/necolas/react-native-web.


Create a component to demo

We'll need a component to display in our live demo, so let's recreate this image of Toad using React Native.


Toad



We can recreate Toad using only <View> components. So first, we need to import <View> at the top of App.js.

    
import { View } from ‘react-native’
    
  

Next, replace <Text>Hello World</Text> in the App.js render method with the JSX below:



<View style={styles.body}>
  <View style={styles.Toad}>
    <View style={styles.Toad__head}>
      <View style={[styles.Toad__spot, styles.Toad__spot__left]} />
      <View style={[styles.Toad__spot, styles.Toad__spot__top]} />
      <View style={[styles.Toad__spot, styles.Toad__spot__right]} />
    </View>

    <View style={styles.Toad__face}>
      <View style={styles.Toad__faceFeatures}>
        <View style={[styles.Toad__eye, styles.Toad__eye__left]} />
        <View style={[styles.Toad__eye, styles.Toad__eye__right]} />
        <View style={[styles.Toad__mouth]}>
          <View style={styles.Toad__tongue} />
        </View>
      </View>
    </View>
  </View>
</View>

React Native requires all styles to be created using StyleSheet, so we need to import the StyleSheet component from react-native.

    
import { View, Stylesheet } from ‘react-native’
    
  

Add the following styles to the bottom of the page.

    // Functions Mode looks like:
const styles = StyleSheet.create({
  body: {
    height: "400px",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    overflow: "hidden"
  },
  Toad: {
    position: "relative"
  },
  Toad__head: {
    width: "300px",
    height: "275px",
    backgroundColor: "white",
    borderWidth: 4,
    borderColor: "black",
    borderBottomLeftRadius: 175,
    borderBottomRightRadius: 175,
    borderTopRightRadius: 250,
    borderTopLeftRadius: 250,
    position: "relative",
    overflow: "hidden"
  },
  Toad__spot: {
    height: "125px",
    width: "125px",
    backgroundColor: "#c4292b",
    borderRadius: "100%",
    position: "absolute"
  },
  Toad__spot__left: {
    height: "140px",
    left: "-50px",
    top: "80px"
  },
  Toad__spot__top: {
    left: "88px",
    top: "0px"
  },
  Toad__spot__right: {
    height: "140px",
    right: "-50px",
    top: "80px"
  },
  Toad__forehead: {
    height: "4px",
    width: "135px",
    backgroundColor: "black",
    position: "absolute",
    left: "87px",
    bottom: "110px",
    zIndex: "10",
    borderRadius: "100%"
  },
  Toad__face: {
    height: "160px",
    width: "150px",
    backgroundColor: "#f0caa5",
    position: "absolute",
    left: "75px",
    bottom: "-50px",
    borderBottomLeftRadius: 80,
    borderBottomRightRadius: 80,
    borderTopRightRadius: 60,
    borderTopLeftRadius: 60,
    borderWidth: 4,
    borderColor: "black"
  },
  Toad__faceFeatures: {
    width: "100%",
    height: "100%",
    position: "relative",
    borderBottomLeftRadius: 80,
    borderBottomRightRadius: 80,
    borderTopRightRadius: 40,
    borderTopLeftRadius: 40
  },
  Toad__eye: {
    height: "35px",
    width: "15px",
    backgroundColor: "#222",
    position: "absolute",
    borderRadius: "100%",
    top: "35px"
  },
  Toad__eye__left: {
    left: "30%"
  },
  Toad__eye__right: {
    left: "60%"
  },
  Toad__mouth: {
    height: "40px",
    width: "60px",
    backgroundColor: "#9f4148",
    borderBottomLeftRadius: 30,
    borderBottomRightRadius: 30,
    borderTopRightRadius: 4,
    borderTopLeftRadius: 4,
    position: "absolute",
    left: "calc(75px - 32px)",
    top: "95px",
    overflow: "hidden"
  },
  Toad__tongue: {
    height: "30px",
    width: "60px",
    backgroundColor: "#d26b74",
    borderRadius: "100px",
    marginTop: "20px"
  }
});
    
  

Now, you should see Toad recreated with <View>.


Implementing React-live


First install:

    
npm install react-live
    
  

Then import all the available components in App.js:


    
import {
  LiveProvider,
  LiveEditor,
  LiveError,
  LivePreview
} from 'react-live'
    
  

Next, comment out the Toad code and add the following to the render method below the commented out Toad code:


    
<LiveProvider code="<strong>This is a live Component</strong>">
  <LivePreview />
  <LiveEditor />
  <LiveError />
</LiveProvider>
    
  

You should see the bolded "This is a live Component" text with the JSX below it. If you edit the JSX, the text or component will update in real time. The <LiveProvider /> simply takes a string of JSX in the code prop and renders that JSX in the <LivePreview /> component.
The <LiveEditor /> component displays the string of JSX as JSX.
Finally, the <LiveError /> component will show any errors that occurred.


Render Toad Live


Uncomment the Toad code from above, copy it, and create a string at the top of the page with the full Toad code. Add the Toad styles above the JSX:


    
const toad = `
  const styles = StyleSheet.create({
    // full style object
  })
<View style={styles.body}>
  <View style={styles.Toad}>
    <View style={styles.Toad__head}>
      <View style={[styles.Toad__spot, styles.Toad__spot__left]} />
      <View style={[styles.Toad__spot, styles.Toad__spot__top]} />
      <View style={[styles.Toad__spot, styles.Toad__spot__right]} />
    </View>

    <View style={styles.Toad__face}>
      <View style={styles.Toad__faceFeatures}>
        <View style={[styles.Toad__eye, styles.Toad__eye__left]} />
        <View style={[styles.Toad__eye, styles.Toad__eye__right]} />
        <View style={[styles.Toad__mouth]}>
          <View style={styles.Toad__tongue} />
        </View>
      </View>
    </View>
  </View>
</View>
`
    
  

Now update the <LiveProvider /> with the toad JSX string.


    
<LiveProvider code={toad}>
  <LivePreview />
  <LiveEditor />
  <LiveError />
</LiveProvider>
    
  

There should be a syntax error shown at the bottom of the page within the <LiveError /> component because react-live is trying to evaluate the JSX inline and running into a style object. To fix this, first add the noInline prop to the <LiveProvider />:


    
<LiveProvider code={toad} noInline>
  <LivePreview />
  <LiveEditor />
  <LiveError />
</LiveProvider>
    
  

Then wrap the Toad JSX in a render() within the string:


    
const toad = `
  const styles = StyleSheet.create({
      // full style object
    })

  render(
    <View style={styles.body}>
        <View style={styles.Toad}>
          <View style={styles.Toad__head}>
            <View style={[styles.Toad__spot, styles.Toad__spot__left]} />
            <View style={[styles.Toad__spot, styles.Toad__spot__top]} />
            <View style={[styles.Toad__spot, styles.Toad__spot__right]} />
          </View>

          <View style={styles.Toad__face}>
            <View style={styles.Toad__faceFeatures}>
              <View style={[styles.Toad__eye, styles.Toad__eye__left]} />
              <View style={[styles.Toad__eye, styles.Toad__eye__right]} />
              <View style={[styles.Toad__mouth]}>
                <View style={styles.Toad__tongue} />
              </View>
            </View>
          </View>
        </View>
      </View>
  );
`
    
  

Scrolling to the bottom of the page again you will see another error “ReferenceError: View is not defined”. By default, react-live does not have references to react-native components, so we need to provide react-live with a reference to both <View /> and StyleSheet to render properly. We can do this with the scope prop which allows the code passed into the code prop access variables and components.


Update <LiveProvider /> as follows:


    
<LiveProvider code={toad} noInline scope={{ View, StyleSheet }} >
  <LivePreview />
  <LiveEditor />
  <LiveError />
</LiveProvider>
    
  

You should see Toad nested inside the <LivePreview /> and all the Toad JSX and styles below. Since this is a live component, you can change the styles or JSX see them update in real time. Try changing Toad's colors or head size, and watch the image update in real time. Check out the react-live docs to learn how to customize the LiveEditor and LivePreview https://github.com/FormidableLabs/react-live.


---
At FullStack Labs, we pride ourselves on our ability to push the capabilities of cutting-edge frameworks like React Native. Interested in learning more about using React Native on the web? Contact us.

Let’s Talk!

We’d love to learn more about your project. Contact us below for a free consultation with our CEO.
Projects Start at $25,000.

FullStack Labs
This field is required
This field is required
Type of project
Reason for contact:
How did you hear about us? This field is required