Many times, as developers we are working on a React website and suddenly the clients ask for a mobile version of the same App, thats when React Native comes in hand, sure you can use almost all the logic behind it, but it becomes a trouble when every html component crashes our app and we have to think about the mobile equivalent of every single Html tag, and of course it never looks the same way.

Thats where we need some other tools, in this POST ill speak about how to make that migration easier with 2 different tools, styled-components and native-base.

Getting Started

First lets create our 2 different projects. One in React-Native and one for React. For both well follow the tutorial offered in both websites.

React goes at it follows

npm install -g create-react-app
create-react-app webapp

cd webapp
npm start

and Native

npm install -g react-native-cli
react-native init NativeApp

cd NativeApp
react-native run-ios

That left us with the both default views. For React in (src/App.js) we got

<div className="App">
  <div className="App-header">
    <img src={logo} className="App-logo" alt="logo" />
    <h2>Welcome to React</h2>
  </div>
  <p className="App-intro">
    To get started, edit <code>src/App.js and save to reload.
  </p>
</div>
</code>

and in Native (index.ios.js)

<View style={styles.container}>
  <Text style={styles.welcome}>
    Welcome to React Native!
  </Text>
  <Text style={styles.instructions}>
    To get started, edit index.ios.js
  </Text>
  <Text style={styles.instructions}>
    Press Cmd+R to reload,{'n'}
    Cmd+D or shake for dev menu
  </Text>
</View>

Now lets add a List a Button and a simple Input to make it more complete. (and delete image tag)

<div className="App">
  <div className="App-header">
    <h2>Welcome to React</h2>
  </div>
  <p className="App-intro">
    To get started, edit <code>src/App.js and save to reload.
  </p>



*    First elem 

*    Second Elem 



<input name="vehicle" value="Bike" />

</div>
</code>

Great, now the thing is how to send exactly this, into a native component, if we paste this directly into our native app we get the following error: Expected a component class, got [object Object] Basically it is caused because it was expecting a native tag and we sent it an HTML tag. So we need to find an alternative route, the usual way is to think whats the equivalent tag for every HTML, change it, and then alter all the CSS so it gets a nice behavior, but thats not easy all the time, as the view gets more complicated, getting its native equivalent gets more tricky.

One way of doing this is with StyledComponents.

Styled-Components

The idea behind styled-component is to separate class looks with its functionality, with this in mind we can create an interface to every HTML tag so we can render them in a native environment, to do this we have to be familiarized with the Natives tags, and create our own. First lets install Styled-Components.

npm install --save styled-components

And then import them in our view

So as we got it so far, we need to create a new component for each HTML tag, so we got DIV, UL-LI, P, Input and H2. For every single one of them well create a new const like this.

const DIV     = styled.View``;
const P       = styled.Text``;
const CODE    = styled.Text``;
const H2      = styled.Text``;
const INPUT   = styled.TextInput``;
const BR      = styled.View``;
const UL      = styled.View``;
const LI      = styled.Text``;

and change our index code to this, altering all HTML tags to our new ones. I know that many of you will cry when they see that UL is a type of View and LI a type of text, the logic behind it is that ul in HTML is a sort of cotainer of all li elements that have the actual text, so we can see it as a div with paragraph inside.

<DIV className="App">
  <DIV className="App-header">
    <H2>Welcome to React</H2>
  </DIV>
  <P className="App-intro">
    To get started, edit <CODE>src/App.js and save to reload.
  </P>



*    First elem 

*    Second Elem 



<INPUT name="vehicle" value="Bike" />

</DIV>
</code>

And there we go, no more errors and it goes nicely, many would say that its the same as changing it manually, but this way you can define the regular behaviour of each element in a single component and then share it through all the views, for example, changing the H2 element to be more accurate to a headline tag in HTML, and adding a few CSS we get the regular HTML behaviour.

const DIV     = styled.View`
  padding: 10px
`;
const P       = styled.Text``;
const CODE    = styled.Text`
  font-family: 'Helvetica';
`;
const H2      = styled.Text`
  font-weight: bold;
  font-size: 20;
`;
const INPUT   = styled.TextInput`
  border: 1px solid black;
`;
const BR      = styled.View``;
const UL      = styled.View`
  padding: 20px
`;
const LI      = styled.Text``;

we get a more appealing design that can be used through all our views with no mayor interaction than changing a few tags. Please note that this doesn’t change the functionality of your app in any way, you can get even a further customization by studying styled-components.

NativeBase

NativeBase is a component library, made to create native apps quickly with very little changes to components themselves. Even thought you would still have to learn each component and see your way through replacing your HTML with nativeBase.

A plus side is that it comes with components such as sidebars, navbars, menus etc that makes your development easier.

First lets install it

npm install native-base --save

react-native link

After we make our install, we need to import the components that we will use in this view.

import { Container, Title, List, ListItem, Input, Text } from 'native-base';

Then change every tag in our index as it follows

<Container className="App">
  <Container className="App-header">
    <Title>Welcome to React</Title>
  </Container>
  <Text className="App-intro">
    To get started, edit <Text>src/App.js</Text> and save to reload.
  </Text>
  <List>
    <ListItem> First elem </ListItem>
    <ListItem> Second Elem </ListItem>
  </List>
  <Input name="vehicle" value="Bike"/>
</Container>

If you run this, you will still get an error, the famous Raw Text, this errors happens when you got a Text outside any tag and Native doesn’t know what to do about it, in our case is the text inside ListItem, ListItem its still a View type container, that means that it isn’t a component that would render a text, to change that we got to use a

<Container className="App">
  <Container className="App-header">
    <Title>Welcome to React</Title>
  </Container>
  <Text className="App-intro">
    To get started, edit <Text>src/App.js</Text> and save to reload.
  </Text>
  <List>
    <ListItem>
      <Text>First elem</Text>
    </ListItem>
    <ListItem>
      <Text>Second Elem</Text>
    </ListItem>
  </List>
  <Input name="vehicle" value="Bike"/>
</Container>

And there we go, we got a more mobile version of what we got before.

Conclusion

NativeBase gives us a template to work with, several components and premade functionalities that can lend us a hand in several applications, things such as NavBars, Forms, MenuBars, etc that already comes with a more mobile style. In the other hand styled-components gives us the ability to even import easily the css that we made already for our web components, so if we got a solid and responsive design for our web we may come in use of that level of customization.

Both of them works perfectly with each other so you can have the good sides of each one, using the more template design that provides nativeBase and a more customizable one that comes with styled-components.