React.js vs. React Native: FIGHT! Making the Transition from Web to Cross-Platform Mobile Development
I’m approaching my 7th week of Flatiron School’s LIVE Software Engineering Bootcamp, and it has been a whirlwind! With that being said, before we jump into the topic at hand, let’s talk a little bit about how I got here…
How I Got Here (Short Version): The Gap
In October 2022, I was unfortunately laid off from an early-stage startup, which, at the time, had run low on runway and had no choice other than to make some cuts. In my time with that company (May 2021-Oct 2022), I served as a creative leader, on a small team, working alongside the CEO to transition their business model from service-driven to software-driven. Essentially, they wanted to build an app to facilitate services that they, to that point, had offered with a more “white-glove,” manual approach. Their ultimate goal was to scale their impact and expand their community.
In a little under a year’s time, working with a team of product designers and developers, (notably, without technical backgrounds, ourselves) we went from an “idea” to live iOS, Android, and web applications!!
They say: “All good things come to an end.” This experience put me in the driver’s seat — and the opportunity to lead design and development of three full-stack applications is something I walked away immensely thankful for. However, with all the great times, new friends, and amazing experiences I had gained, after the opportunity came to an end, I felt as though I was back at “square one.”
From there, I surmised that it was time for me to build something from the ground-up, not as an employee, but as an owner and a founder.
In November 2022, inspired by my background in education, a desire to “make change” in the education space, and a few experiences collaborating with local and state education agencies (like TEA), Cast was born.
Despite strong sentiments on local issues like education, healthcare, and taxes, many eligible voters do not participate in local elections, often due to lack of information, general apathy, and/or issues of accessibility. I saw this first hand as questionable (a nice word for it) legislation went into effect, negatively impacting standards and curriculum for K-12 students, time-and-time again.
My vision for Cast, from the beginning, has been a mobile application that leverages AI models and open-source voter information to tackle this gap, making it easier to keep up with local elections, allowing users to quickly make informed election choices and drive impact quickly and easily, based on issues they care about.
After a year of highs, lows, wins, losses, break-throughs and roadblocks, I saw my lack of technical skills as the “final” gap between where I was and where I wanted to be with Cast. Here I was, trying to succeed as a founder in an industry where I did not know the craft.
Cue: Flatiron School’s Software Engineering Bootcamp.
The Gap That Remained: Mobile Development
The SE Live Bootcamp at Flatiron School has been a groundbreaking experience for me… and I’m not even half-way through! The opportunity to learn programming languages like HTML, CSS, JavaScript (React), Python (Flask), Ruby (Ruby on Rails), and more, has made me capable of things that I once thought were impossible for me.
I do not take this feeling, this opportunity, or this program for granted, but, unfortunately: I could not be satisfied with it. While we learn the fundamentals of what it takes to be full-stack web developers, my ability to execute a vision for a mobile application, even at completion of the program, would still fall short. With that being said, I sought ways that I could close what I felt was the gap that remained: mobile development.
In no better fashion than I could have planned, in researching mobile development as we progressed into React… I came across what, to me, at the time, felt like a break-through solution to my problem: React Native.
What is React Native?
React Native is an open-source framework for developing applications for Android, iOS, and other platforms using JavaScript and React. It was released by Facebook in 2015 (following React in 2013) and has since been maintained by a community of developers worldwide.
React Native is most famous for its cross-platform development capabilities, allowing developers to create platform-specific versions of components. Instead of building applications natively for each platform, using languages like Objective C and Swift (iOS) or Java and Kotlin (Android), developers can build their codebase just once and use it for both iOS and Android applications. (Wow!)
React, the JavaScript library that React Native is built upon, provides developers with building blocks for development, such as pre-written code and configurations, but these building blocks are web components, not native components. React Native works by using a ‘bridge’ between the application and the target platform, allowing communication between the JavaScript and native systems (like iOS, Android, Windows, and TV apps).
Similarities between React and React Native:
JSX: They both use JSX, a syntax extension that allows you to write HTML-like code in your JavaScript files.
// React and React Native
const element = <h1>Hello, world!</h1>;
Hooks: Hooks like useState
and useEffect
are common in both, making state management and side effects handling consistent across platforms.
// React and React Native
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
...
);
}
Data Fetching: Methods for fetching data like GET, POST, and PATCH are similar in both environments.
// React and React Native
fetch('https://api.example.com/items')
.then(response => response.json())
.then(data => console.log(data));
Major Differences between React and React Native:
How It All Works: React Language Processing
React.js and React Native, while sharing a common lineage, have distinct ways of processing code. React.js takes your JSX (a syntax extension that allows you to write HTML in JavaScript) and compiles it into JavaScript. This JavaScript then interacts with the virtual-DOM (Document Object Model), a lightweight copy of the actual DOM. This approach enables React.js to be incredibly efficient in updating the user interface in a web browser.
In contrast, React Native follows a slightly different path. It also begins with JSX, which is then transformed into JavaScript. However, instead of targeting the virtual-DOM, React Native translates this JavaScript into native code that is compatible with the device’s processor (iPhone, Android device, TV, etc.). This unique process allows React Native apps to leverage the full potential of the device’s capabilities, providing a smoother and more native-like user experience on mobile platforms.
HTML-like Elements vs. React Native Components:
In the realm of React.js, developers are accustomed to using HTML-like JSX elements such as <div>
, <h1>
, <span>
, and <img>
to build their user interfaces. This familiarity with HTML makes transitioning to React.js smoother for those with a background in web development.
// React.js
const MyComponent = () => (
<div>
<h1>Hello World</h1>
<img src="image.png" alt="example"/>
</div>
);
On the other hand, React Native introduces a new set of components, specifically designed to work in the mobile environment. These include <View>
, <Text>
, <ScrollView>
, <Image>
, and more. These components are not mere replicas of HTML elements but are instead tailored to provide mobile-specific functionalities and interactions. This divergence in component sets underscores the adaptability of the React ecosystem to different environments, albeit with a learning curve for those moving from web to mobile development.
// React Native
import { View, Text, Image } from 'react-native';
const MyComponent = () => (
<View>
<Text>Hello World</Text>
<Image source={{ uri: 'image.png' }} />
</View>
);
CSS Stylesheets vs. React StyleSheet API: Styling
Styling in React.js closely resembles traditional web development practices, where CSS stylesheets are linked externally or defined within the component. Developers can leverage their existing knowledge of CSS to style their React.js applications. This familiarity is advantageous for those transitioning from conventional web development to React.js.
<!-- React.js -->
<link rel="stylesheet" href="/style.css" />
In contrast, React Native employs a different approach to styling, utilizing the StyleSheet API. This API (imported from the react-native
package) allows developers to define their styles in a JavaScript object, which React Native then translates into native styles on the mobile platform. This method ensures that the styling is optimized for mobile performance and interaction, but it also means that developers need to adapt to a different way of thinking about and applying styles in their applications.
// React Native
import { StyleSheet, View } from 'react-native';
const styles = StyleSheet.create({
container: {
padding: 20,
backgroundColor: 'blue'
}
});
const MyComponent = () => (
<View style={styles.container}></View>
);
Gestures or No Gestures, That is the Question:
React Native also sets itself apart from React.js through its support for mobile-specific interactions, such as gestures, through it’s react-native-gesture-handler
library. The gesture handler provides a robust set of tools and components to handle swipes, pinches, and other gestures that are integral to a native mobile experience. Here are some examples:
Swipeable Gesture: The react-native-gesture-handler
library provides a Swipeable
component that can be used to make a component swipeable. For example, you can use it to make a list item swipeable.
import Swipeable from 'react-native-gesture-handler/Swipeable';
<Swipeable
renderLeftActions={() => <LeftActions />}
renderRightActions={() => <RightActions />}
>
<ListItem {...item} />
</Swipeable>
In this example, LeftActions
and RightActions
are components that define the actions to be taken when the user swipes left or right. The ListItem
component is the content that the user can swipe.
Tap Gesture: The react-native-gesture-handler
library also provides a TapGestureHandler
component that can be used to handle tap gestures. For example, you can use it to handle single and double tap gestures.
import { TapGestureHandler } from 'react-native-gesture-handler';
<TapGestureHandler
numberOfTaps={2}
onHandlerStateChange={({ nativeEvent }) => {
if (nativeEvent.state === State.ACTIVE) {
// Handle double tap
}
}}
>
<View>
<Text>Double tap me!</Text>
</View>
</TapGestureHandler>
In this example, the numberOfTaps
prop is set to 2
to handle double tap gestures. The onHandlerStateChange
prop is a function that is called when the gesture state changes. If the gesture state is State.ACTIVE
, it means that the user has completed the double tap gesture.
This feature highlights one of the fundamental differences between web and mobile development — the way users interact with the device, and hence the application itself. React.js, being focused on web development, does not inherently support these mobile-specific gestures.
React Router vs. React Navigation: Routing
Navigation in React.js is typically handled by React Router, a powerful and popular library for enabling navigation in web applications. React Router allows developers to define routes and navigate between different screens within a web application, using concepts familiar to web development.
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
function App() {
return (
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
);
}
function Home() {
return <h1>Home</h1>;
}
function About() {
return <h1>About</h1>;
}
In contrast, React Native utilizes React Navigation, a framework specifically designed for mobile apps. React Navigation provides a more mobile-centric approach to navigation, offering features like stack navigation, tab navigation, and drawer navigation, which are common in mobile apps.
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Details" component={Details} />
</Stack.Navigator>
</NavigationContainer>
);
}
function Home({ navigation }) {
return (
<View>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function Details() {
return <Text>Details</Text>;
}
This difference in navigation approaches is indicative of the distinct user experience and design paradigms of web and mobile platforms.
Conclusion: And the Winner is… JavaScript!
Ultimately, the true champion in this battle isn’tReact or React Native… it’s JavaScript. The versatility of JavaScript, coupled with the power of React’s ecosystem, has revolutionized cross-platform development. React’s adaptability to different environments, from web browsers to mobile devices, showcases the miracles JavaScript and its frameworks can achieve, making it an invaluable asset for developers worldwide.
Whether you’re building a web application with React.js or a mobile app with React Native, JavaScript remains the unifying force, driving innovation and efficiency in the software development world.
If interested in learning more about React Native, I recommend Meta’s React Native Specialization (8 total courses) available via Coursera. For Flatiron students who are already familiar with React, I would recommend taking only Course 1 (Introduction to Mobile Development), 4 (React Native), and 5 (Working with Data).
Happy coding!