React to React Native: Tips and tricks for your journey

Vilva Athiban P B
Omio Engineering
Published in
5 min readJan 10, 2020

React Native is gaining popularity these days and many people try to create React Native components out of their existing React ones. This process is not always straightforward so we have created some quick tips to make the migration smooth and error-free.

1. Replace HTML elements with React Native components

The first and most important step in migration is to replace all the HTML elements — as React Native doesn’t support HTML — with the React Native components. For instance, div/section should be replaced with View component and h1 , h2 , … h6 , p and similar text-based elements should be replaced with Text component. For example:

// Web / HTML Component:
const TextComponent = ({content}) => <h1>{content}</h1>
// React - Native version of above Component:import { Text } from 'react-native';const TextComponent = ({content}) => <Text>{content}</Text>

Such React Native components compile into Native code based on the platform and, hence, constitute the fundamental building blocks of the app.

2. Conditional rendering of components can be tricky

Conditional rendering is one of the commonly used patterns in React. Say, we are conditional rendering TestComponent as follows:

<View>  //React Native
{ifTheConditionIsTrue && <TestComponent>}
</View>

The above code works fine in React Native until the variable `ifTheConditionIsTrue` is an empty string. If ifTheConditionIsTrue becomes an empty string, React Native starts expecting a <Text> component to encapsulate it and break the app.

The solution is type coercion. Adding a !! before ifTheConditionIsTrue will convince React Native that the variable is a boolean. The solution looks like this:

<View>  //React Native
{!!ifTheConditionIsTrue && <TestComponent>}
</View>

If you are using typescript, nullish coalescing is also an option as you can use the benefits of the ternary operation and still maintain the readability like so:

<View>  //React Native
{ifTheConditionIsTrue ?? <TestComponent>}
</View>

Since nullish coalescing acts internally as a ternary operator, React Native won't expect a <Text> component if ifTheConditionIsTrue is an empty string.

3. You always click so, learn to press.

In React, we use onClick synthetic events in components. As we don't use a mouse on the mobile phone (yet), we don't have an onClick event. Instead, we have a <TouchableOpacity onPress={}> component, which handles press events in mobile phones. Hence, all the onClick events should be changed to onPress in order to execute the callback when interacting with the components.

4. Platform-agnostic components pose a challenge

When we build an app using React Native, the code gets compiled into Native code depending on the platform (iOS or Android). Maintaining consistency across platforms is quite difficult, especially with the Picker/Select/DropDown. For instance, the native picker component resembles a dropdown in Android and opens a model with options in iOS. If you want to maintain a consistent design, either build a custom component or use libraries such as react-native-picker-select.

5. SVGs

Handling SVGs in React Native is one of the most difficult things. Check out this article to find out how to deal with icons in React Native, which are mono-color SVG. If you want to render “complex” SVGs with more than one color or attributes, you should use npm packages such asreact-native-svg.

6. Ditch CSS

React Native doesn’t support CSS (SASS/LESS)and hence we will have to either use aCSS-in-JS solution or StyleSheet from React Native. Of course, inline-css is always an option with the least priority.

A personal suggestion is to use styled-components as they enable reuse of existing CSS using its css package wherein you may pass CSS as a string without changing much. And if you are already using styled-components for your React components, it’s quite convenient because it provides the same API to style in both React and React Native. This increases the development speed substantially.

A detailed explanation of the effective usage of styled components can be found in this article, which also covers how to handle inline styles with styled components.

7. Inline styles

Inline styles — which can be avoided — are written as objects and accept string values in px for React components. But in React Native such values should be passed as numbers without px. Values in pixels(inline styles) tend to break React Native.

Also, React Native doesn't support shorthand CSS properties in styles. For instance, padding : 10px will break React Native. The individual properties should be listed as follows:

style = {{
paddingTop: 10px,
paddingBottom: 10px,
paddingLeft: 10px,
paddingRight: 10px,
}}

To avoid all these issues, it's better to use a CSS-in-JS solution.

8. FlexBox is key

Flexbox can be used with React Native and it makes it a lot easier for developers to maintain layouts between React and React Native. However, in desktop, the default value for flex-direction is row, while in React Native the default value is column.

Hence to maintain the uniform layout, we need to specify the value of flex-direction.

If you are new to Flexbox or just lazy like I am, Facebook has an interactive tool called Yoga, which creates complex layouts and directly issues codes to React Native.

9. Use styled components with animated components

In the case of React components, we use styled-components as follows:

import ReactComponent from './ReactComponent';
import styled from 'styled-components';
const StyledReactComponent = styled(ReactComponent)`
/* Styles goes here */
`

In React Native, we have a set of Animated components — used for Animations — which can’t be used with styled-components in a similar way. styled(Animated.Text) will issue an error. How does one solve this issue?

Instead of directly using the Animated.Text component, we should leverage the createAnimatedComponent function of the Animated class and create our own component. We can use this custom component styled-components as below.

const CustomAnimatedText = Animated.createAnimatedComponent(Text);const StyledCustomAnimatedText = styled(CustomAnimatedText)`
/* Styles goes here */
`

10. Invalid styling properties

React Native doesn't support all CSS properties supported by the browser. For instance, properties such asposition: fixed are not supported but position: absolute is supported. Another such example is cursor: pointer.

This React Native cheatsheet might come in handy when you are searching for styles supported in React Native.

11. Background images

Are you a CSS fanboy who uses background-image extensively? I have bad news for you: React Native doesn't support background-image and you will have to use the ImageBackground component of React -Native to set an image as background. It goes something like this:

// Background Image - Web 
// (Using inline styles to show the difference)
const BackgroundImage = ({ backgroundURL }) => {
return (
<div
style={{
width: '100%',
height: '100%',
backgroundImage: `url(${backgroundURL})`
}}
>
<h1> Dummy Content </h1>
</div>
)};
// React Native version of the componentconst BackgroundImage = ({ backgroundURL }) => {
return (
<ImageBackground
source={{ uri: backgroundURL }}
style={{width: '100%', height: '100%'}}
>
<Text> Dummy Content </Text>
</ImageBackground>
)};

React Native, unlike the web, needs to build the project and these errors will block the developer from running the app. Therefore, it is quite important to fix them. The above tips will definitely help in the migration process and save a lot of time in fixing errors.

Do you have some helpful migration tips and tricks? Please let me know in the comments below. Let’s stay away from bright RED ERROR screens.

Interested in experimenting and learning? Join us!

--

--

Vilva Athiban P B
Omio Engineering

9+ years of Experience in React-Redux / NodeJS / GraphQL / TypeScript. https://vilvaathiban.com