DEV Community

Cover image for Responsive Space Tourism App with React Native: What I Built & What I Learned
Angel Umeh
Angel Umeh

Posted on

Responsive Space Tourism App with React Native: What I Built & What I Learned

Table of Contents

Overview

For my second swim in React Native development, I tackled a Frontend Mentor challenge to build a space tourism app.

This was my second project built with React Native & Expo, and is the second project in my 60-day React Native challenge.

About the Project

Goals

  • Build my second React Native cross-platform app
  • Build on and advance in styling in React Native & writing CSS-in-JS
  • Implement improved interactivity in my app
  • Learn about & implement data persistence with AsyncStorage

Tools & Stack

  • React Native + Expo
  • React Native Animated API
  • TypeScript
  • AsyncStorage
  • Route management with Expo Router

I primarily used Expo Router for navigation, though React Navigation could also have been a fit. I chose Expo Router for its file-based simplicity.

Features

This is an interactive space tourism introduction. Users can:

  • View each page
  • Toggle between the tabs to see new information
  • View the optimal layout for each of the website's pages depending on their device's screen size
  • See hover states for all interactive elements on the page. On native devices, “hover states” translate to touch feedback rather than mouse hover.
  • [Extra] Come back to their last viewed sections on each page

Links & Demo

You can find the app here:

This live link is the web export of the React Native app via Expo, deployed on Netlify.

Some snippets:

Mobile Screenshots:

Home - Mobile
Destination - Mobile
Crew - Mobile
Technology - Mobile

Desktop Screenshots:
Home - Desktop
Destination - Desktop
Crew - Desktop
Technology - Desktop

What I learned

More React Native Components

I discovered more React Native components in this project, a little further removed from web development this time.

<ImageBackground source={getBg()} style={styles.bg} resizeMode="cover">
    <ScrollView contentContainerStyle={styles.content}>
        // Your content here
    </ScrollView>
</ImageBackground>
Enter fullscreen mode Exit fullscreen mode

I learned to use ImageBackground for full-screen background images that adapt to different screen sizes, and ScrollView with contentContainerStyle attribute for better content layout control within scrollable areas.

State Management with React useRef

useState remained an important part of my toolbox, managing the animation states, but useRef allowed me to maintain animation values that would update frequently but that don't trigger re-renders.

const slideAnim = useRef(new Animated.Value(50)).current;
const scaleAnim = useRef(new Animated.Value(0.95)).current;
Enter fullscreen mode Exit fullscreen mode

Data Persistence with AsyncStorage

Just like JS localStorage, AsyncStorage allowed me to store and persist user choices like the selected destination or the last viewed crew member.

// Save user selection
await AsyncStorage.setItem('lastDestination', destination.name);

// Load on app startup
const lastDestination = await AsyncStorage.getItem('lastDestination');
Enter fullscreen mode Exit fullscreen mode

Improved Animations & Gestures

I got a much clearer understanding of the anatomy of a typical gesture, thanks to @eveningkid's YouTube tutorials. I was able to progress from single animations to coordinated animation systems. On re-reading the React Native Animated docs, I found methods like sequence(), parallel(), stagger(), and loop(). I mostly used parallel():

Animated.parallel([
    Animated.timing(slideAnim, { toValue: 0, duration: 400 }),
    Animated.timing(scaleAnim, { toValue: 1, duration: 400 })
]).start();
Enter fullscreen mode Exit fullscreen mode

Distinct Responsive Layouts based on screen size

Rather than just scaling elements, I learned to create fundamentally different layouts, where mobile stacks all the page content vertically, while desktop uses a two-column layout, each optimized for their respective interaction patterns.

Challenges Faced

  • Platform differences: \ I realized that many functions, effects or other behaviors that seem normal on web may not apply on real devices.
menu: {
    backgroundColor: 'rgba(11, 13, 23, 0.15)',
    backdropFilter: 'blur(40px)', // Works in browser, not iOS
}
Enter fullscreen mode Exit fullscreen mode
  • Gestures: \ Making a functional multi-part gesture required me to properly understand the anatomy of a gesture. @eveningkid's tutorials helped me get that gestures are comprised of a start, a behavior, and a release.

Final Thoughts

I enjoyed building this app. It was quite the challenge, but it helped me flex my layouts muscle.

I also learned to create animation systems for smooth effects, and implement slightly more complicated gestures. Thanks to this project, I learned the anatomy of a gesture, and this will serve as a building block for more complicated ones in the future.

This project is part of my summer side quest.
You can follow me on X & GitHub to keep up with the full challenge.

Top comments (1)

Collapse
 
skyaccess profile image
SkyAccess

Thank you, interesting