React Native

React Native and Expo patterns for building performant mobile apps. Covers list performance, animations with Reanimated, navigation, UI patterns, stat

What Is React Native?

React Native is a popular open-source framework developed by Meta (formerly Facebook) for building mobile applications using JavaScript and React. Unlike traditional native development with Swift (iOS) or Kotlin/Java (Android), React Native enables developers to write a single codebase that runs on both iOS and Android platforms. It achieves this by rendering native components via a JavaScript bridge, resulting in apps that feel and perform like true native experiences. React Native also integrates seamlessly with Expo, a toolkit that streamlines development, testing, and deployment of mobile apps.

Why Use React Native?

React Native offers several compelling advantages for mobile development teams:

  • Cross-platform development: Write once, deploy on both iOS and Android, reducing engineering effort and maintenance overhead.
  • Native performance: Unlike hybrid approaches that use web views, React Native renders real native components, ensuring a smooth user experience.
  • Rich ecosystem: Benefit from a vibrant community, reusable third-party libraries, and ongoing updates.
  • Faster iteration: Features like hot reloading and Expo’s development tools accelerate the build-test-debug cycle.
  • Flexibility: Easily mix JavaScript-based UI with native modules for advanced use cases.
  • Scalability: Suitable for startups and enterprises alike, React Native powers apps from small prototypes to large-scale production deployments.

How to Get Started

To start building with React Native, you can choose between the bare React Native CLI and the Expo managed workflow. Expo simplifies the process by handling much of the native configuration for you.

Basic setup with Expo:

  1. Install Expo CLI:

    npm install -g expo-cli
  2. Create a new project:

    expo init MyAwesomeApp
  3. Start the development server:

    cd MyAwesomeApp
    expo start
  4. Edit your app:
    Begin modifying the App.js file. The changes will hot reload in your simulator or physical device.

For existing React developers, the component model will feel familiar. For new developers, Expo provides clear documentation and a fast feedback cycle.

Key Features

React Native and Expo provide a robust foundation for building performant, scalable mobile apps. This skill covers several core areas:

  • List Performance: Efficient handling of large or dynamic lists using virtualized components (FlatList, FlashList). Poorly optimized lists are the most common cause of slow, unresponsive interfaces.
  • Animations: Smooth, interactive animations using the Reanimated library, which provides native-driven performance for complex transitions and gestures.
  • Navigation: Declarative and type-safe navigation patterns, including stack, tab, and drawer navigators (with libraries like React Navigation or Expo Router).
  • UI Patterns: Consistent, platform-adaptive UI components and theming, leveraging libraries such as React Native Paper, NativeBase, or custom implementations.
  • State Management: Managing local and global state using solutions like React Context, Redux, or Zustand.
  • Platform-Specific Code: Handling device differences, APIs, and styling for iOS and Android within a unified codebase.
  • Expo Workflows: Using Expo for streamlined development, asset management, over-the-air updates, and simplified build and deployment processes.

Best Practices

To ensure your React Native apps are performant and maintainable, follow these best practices:

1. List

Performance (CRITICAL)

Lists are the primary source of performance issues in mobile apps. Improper use of list components can lead to sluggish interfaces and memory leaks.

  • Never use <ScrollView> for large or dynamic data sets.

    // Bad: Renders all items at once
    <ScrollView>
      {data.map(item => <ListItem key={item.id} {...item} />)}
    </ScrollView>
    
    // Good: Only renders what’s visible
    <FlatList
      data={data}
      renderItem={({ item }) => <ListItem {...item} />}
      keyExtractor={item => item.id}
    />

    Use <FlatList> or <FlashList> instead, which are virtualized and render only the visible items.

  • Always provide a stable keyExtractor prop. This prevents unnecessary re-renders and ensures each item is uniquely identified.

    <FlatList
      data={data}
      keyExtractor={item => item.id}
      renderItem={...}
    />

2. Animations with

Reanimated

For smooth, complex animations:

  • Use react-native-reanimated.
  • Avoid JavaScript-driven animations for interactions (like drag or swipe); use native-driven APIs instead.
import Animated, { FadeIn } from 'react-native-reanimated';

<Animated.View entering={FadeIn.duration(500)}>...</Animated.View>

3. Navigation

Utilize established navigation solutions:

4. Platform-Specific

Code

  • Use the Platform module for conditional logic.
    import { Platform } from 'react-native';
    const padding = Platform.OS === 'ios' ? 20 : 0;

5. State

Management

  • Start with React’s built-in state/context for small projects.
  • For larger apps, consider Redux, Zustand, or Jotai for scalable state management.

Important Notes

  • Always profile performance, especially for list-heavy screens.
  • Update dependencies regularly to benefit from performance and security improvements.
  • Test on both iOS and Android devices, as behavior and performance can differ.
  • Use Expo for rapid prototyping and deployment, but consider ejecting to bare React Native if you need advanced native modules.
  • Stay updated with best practices—React Native’s ecosystem evolves quickly.

Applying these patterns and practices ensures your mobile apps are robust, performant, and maintainable as they scale.