
Introduction
React Native is built around the concept of components, which are the building blocks of your mobile application’s user interface. Understanding React Native components is fundamental to becoming proficient in React Native development. In this chapter, we’ll explore what components are, how they work, and dive into the core components provided by React Native.
What Are React Native Components?
Components in React Native are independent, reusable pieces of code that return elements describing what should appear on the screen. They serve as the foundation for building user interfaces in React Native applications.
Types of Components in React Native
There are two primary types of components in React Native:
- Class Components: Traditional component type that uses ES6 classes.
- Functional Components: Modern approach that uses JavaScript functions and React Hooks.
Class Component Example:
import React, { Component } from 'react';
import { Text, View } from 'react-native';
class HelloWorld extends Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Hello, World!</Text>
      </View>
    );
  }
}
export default HelloWorld;
Functional Component Example:
import React from 'react';
import { Text, View } from 'react-native';
const HelloWorld = () => {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>Hello, World!</Text>
    </View>
  );
};
export default HelloWorld;
Core Components in React Native
React Native provides a set of essential, built-in components that map directly to native UI elements on both iOS and Android platforms. These are known as core components.
View
View is the most fundamental component for building a UI. It’s a container that supports layout with flexbox, style, touch handling, and accessibility controls.
import React from 'react';
import { View, StyleSheet } from 'react-native';
const ViewExample = () => {
  return (
    <View style={styles.container}>
      <View style={styles.box} />
      <View style={styles.box} />
      <View style={styles.box} />
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-around',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  box: {
    width: 80,
    height: 80,
    backgroundColor: 'steelblue',
  },
});
export default ViewExample;
Text
Text displays text and supports nesting, styling, and touch handling.
import React from 'react';
import { Text, StyleSheet } from 'react-native';
const TextExample = () => {
  return (
    <Text style={styles.baseText}>
      This is the base text
      <Text style={styles.nestedText}> and this is nested text</Text>
    </Text>
  );
};
const styles = StyleSheet.create({
  baseText: {
    fontFamily: 'Cochin',
    fontSize: 18,
    fontWeight: 'bold',
  },
  nestedText: {
    color: 'red',
  },
});
export default TextExample;
Image
Image displays different types of images, including network images, static resources, and images from the local disk.
import React from 'react';
import { View, Image, StyleSheet } from 'react-native';
const ImageExample = () => {
  return (
    <View style={styles.container}>
      {/* Loading a local image */}
      <Image
        source={require('./assets/local-image.png')}
        style={styles.localImage}
      />
      {/* Loading a network image */}
      <Image
        source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
        style={styles.networkImage}
      />
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  localImage: {
    width: 200,
    height: 200,
    margin: 10,
  },
  networkImage: {
    width: 100,
    height: 100,
    margin: 10,
  },
});
export default ImageExample;
TextInput
TextInput allows users to enter text. It has a wide range of configurable properties to customize the input behavior.
import React, { useState } from 'react';
import { View, TextInput, Text, StyleSheet } from 'react-native';
const TextInputExample = () => {
  const [text, setText] = useState('');
  return (
    <View style={styles.container}>
      <TextInput
        style={styles.input}
        placeholder="Type something here..."
        onChangeText={text => setText(text)}
        value={text}
      />
      <Text style={styles.text}>
        You typed: {text}
      </Text>
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    paddingHorizontal: 10,
    marginBottom: 20,
  },
  text: {
    fontSize: 16,
  },
});
export default TextInputExample;
ScrollView
ScrollView is a generic scrolling container that can host multiple components and views.
import React from 'react';
import { ScrollView, View, Text, StyleSheet } from 'react-native';
const ScrollViewExample = () => {
  return (
    <ScrollView style={styles.container}>
      {[...Array(20)].map((_, i) => (
        <View key={i} style={styles.box}>
          <Text style={styles.text}>Item {i + 1}</Text>
        </View>
      ))}
    </ScrollView>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  box: {
    height: 100,
    marginVertical: 10,
    backgroundColor: 'skyblue',
    justifyContent: 'center',
    alignItems: 'center',
  },
  text: {
    fontSize: 20,
    fontWeight: 'bold',
},
});
export default ScrollViewExample;
Button
Button provides a basic button component that renders nicely on any platform.
import React from 'react';
import { View, Button, Alert, StyleSheet } from 'react-native';
const ButtonExample = () => {
  return (
    <View style={styles.container}>
      <Button
        title="Press Me"
        onPress={() => Alert.alert('Button pressed!')}
        color="#841584"
      />
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
});
export default ButtonExample;
Touchable Components
React Native provides several touchable components to handle touch events:
- TouchableHighlight: Changes opacity when pressed
- TouchableOpacity: Changes opacity when pressed (more customizable)
- TouchableWithoutFeedback: No visual feedback when pressed
- Pressable: Modern touchable component with more control over interactions
import React from 'react';
import { View, Text, TouchableHighlight, TouchableOpacity, StyleSheet, Alert } from 'react-native';
const TouchableExample = () => {
  return (
    <View style={styles.container}>
      <TouchableHighlight
        style={styles.button}
        onPress={() => Alert.alert('TouchableHighlight pressed!')}
        underlayColor="#DDDDDD"
      >
        <Text style={styles.buttonText}>TouchableHighlight</Text>
      </TouchableHighlight>
      <TouchableOpacity
        style={styles.button}
        onPress={() => Alert.alert('TouchableOpacity pressed!')}
      >
        <Text style={styles.buttonText}>TouchableOpacity</Text>
      </TouchableOpacity>
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
  button: {
    backgroundColor: '#2196F3',
    padding: 15,
    borderRadius: 5,
    marginVertical: 10,
    alignItems: 'center',
  },
  buttonText: {
    color: 'white',
    fontWeight: 'bold',
  },
});
export default TouchableExample;
Switch
Switch is a controlled component that renders a boolean input.
import React, { useState } from 'react';
import { View, Switch, Text, StyleSheet } from 'react-native';
const SwitchExample = () => {
  const [isEnabled, setIsEnabled] = useState(false);
  const toggleSwitch = () => setIsEnabled(previousState => !previousState);
  return (
    <View style={styles.container}>
      <Switch
        trackColor={{ false: "#767577", true: "#81b0ff" }}
        thumbColor={isEnabled ? "#f5dd4b" : "#f4f3f4"}
        ios_backgroundColor="#3e3e3e"
        onValueChange={toggleSwitch}
        value={isEnabled}
      />
      <Text style={styles.text}>
        Switch is {isEnabled ? 'ON' : 'OFF'}
      </Text>
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  text: {
    marginTop: 20,
    fontSize: 18,
  }
});
export default SwitchExample;
ActivityIndicator
ActivityIndicator displays a loading indicator.
import React, { useState, useEffect } from 'react';
import { View, ActivityIndicator, StyleSheet, Text } from 'react-native';
const ActivityIndicatorExample = () => {
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    // Simulate data loading
    const timer = setTimeout(() => {
      setLoading(false);
    }, 3000);
    return () => clearTimeout(timer);
  }, []);
  return (
    <View style={styles.container}>
      {loading ? (
        <View style={styles.loadingContainer}>
          <ActivityIndicator size="large" color="#0000ff" />
          <Text style={styles.loadingText}>Loading...</Text>
        </View>
      ) : (
        <Text style={styles.content}>Content Loaded!</Text>
      )}
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  loadingContainer: {
    alignItems: 'center',
  },
  loadingText: {
    marginTop: 10,
    fontSize: 16,
  },
  content: {
    fontSize: 20,
    fontWeight: 'bold',
  },
});
export default ActivityIndicatorExample;
Custom Components
Creating custom components allows you to build reusable UI elements for your application.
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
// Custom Button Component
const CustomButton = ({ title, onPress, backgroundColor = '#2196F3' }) => {
  return (
    <TouchableOpacityÂ
      style={[styles.button, { backgroundColor }]}Â
      onPress={onPress}
    >
      <Text style={styles.buttonText}>{title}</Text>
    </TouchableOpacity>
  );
};
// Using the Custom Component
const CustomComponentExample = () => {
  return (
    <View style={styles.container}>
      <CustomButtonÂ
        title="Primary Button"Â
        onPress={() => alert('Primary button pressed!')}Â
      />
      <CustomButtonÂ
        title="Secondary Button"Â
        onPress={() => alert('Secondary button pressed!')}Â
        backgroundColor="#FF9800"
      />
      <CustomButtonÂ
        title="Danger Button"Â
        onPress={() => alert('Danger button pressed!')}Â
        backgroundColor="#F44336"
      />
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
  button: {
    padding: 15,
    borderRadius: 5,
    marginVertical: 10,
    alignItems: 'center',
  },
  buttonText: {
    color: 'white',
    fontWeight: 'bold',
    fontSize: 16,
  },
});
export default CustomComponentExample;
Component Composition
Component composition is a powerful pattern in React Native that involves building complex UIs by combining simpler components.
import React from 'react';
import { View, Text, StyleSheet, Image } from 'react-native';
// Card Header Component
const CardHeader = ({ title, subtitle }) => {
  return (
    <View style={styles.header}>
      <Text style={styles.title}>{title}</Text>
      <Text style={styles.subtitle}>{subtitle}</Text>
    </View>
  );
};
// Card Content Component
const CardContent = ({ children }) => {
  return <View style={styles.content}>{children}</View>;
};
// Card Footer Component
const CardFooter = ({ children }) => {
  return <View style={styles.footer}>{children}</View>;
};
// Card Component that composes the above components
const Card = ({ title, subtitle, image, description, footer }) => {
  return (
    <View style={styles.card}>
      <CardHeader title={title} subtitle={subtitle} />
      <Image source={image} style={styles.image} />
      <CardContent>
        <Text>{description}</Text>
      </CardContent>
      <CardFooter>{footer}</CardFooter>
    </View>
  );
};
// Example Usage
const CompositionExample = () => {
  return (
    <View style={styles.container}>
      <Card
        title="Beautiful Sunset"
        subtitle="Captured yesterday"
        image={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
        description="This stunning sunset was captured at the beach yesterday evening. The colors were absolutely breathtaking."
        footer={
          <Text style={styles.footerText}>Photo by: John Doe</Text>
        }
      />
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    justifyContent: 'center',
  },
  card: {
    backgroundColor: 'white',
    borderRadius: 10,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5,
    overflow: 'hidden',
  },
  header: {
    padding: 15,
    backgroundColor: '#f8f8f8',
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
  },
  subtitle: {
    fontSize: 14,
    color: '#666',
    marginTop: 5,
  },
  image: {
    width: '100%',
    height: 200,
  },
  content: {
    padding: 15,
  },
  footer: {
    padding: 15,
    borderTopWidth: 1,
    borderTopColor: '#eee',
  },
  footerText: {
    fontSize: 12,
    color: '#666',
    textAlign: 'right',
  },
});
export default CompositionExample;
Platform-Specific Components
React Native allows you to create platform-specific components using the Platform module.
import React from 'react';
import { View, Text, StyleSheet, Platform } from 'react-native';
const PlatformSpecificExample = () => {
  return (
    <View style={styles.container}>
      <Text style={styles.headerText}>
        Platform-Specific Components
      </Text>
      {/* Platform-specific code */}
      {Platform.OS === 'ios' ? (
        <Text style={styles.platformText}>This is rendered only on iOS</Text>
      ) : (
        <Text style={styles.platformText}>This is rendered only on Android</Text>
      )}
      {/* Platform-specific styles */}
      <View style={styles.box}>
        <Text style={styles.boxText}>
          This box has platform-specific styling
        </Text>
      </View>
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  headerText: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
  },
  platformText: {
    fontSize: 16,
    color: 'blue',
    marginBottom: 20,
  },
  box: {
    width: 200,
    height: 100,
    justifyContent: 'center',
    alignItems: 'center',
    ...Platform.select({
      ios: {
        backgroundColor: '#FFCCCC',
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.25,
        shadowRadius: 3.84,
      },
      android: {
        backgroundColor: '#CCFFCC',
        elevation: 5,
      },
    }),
  },
  boxText: {
    textAlign: 'center',
    ...Platform.select({
      ios: {
        color: 'red',
      },
      android: {
        color: 'green',
      },
    }),
  },
});
export default PlatformSpecificExample;
Component Best Practices
1. Keep Components Small and Focused
Components should ideally do one thing well. If a component becomes too complex, consider breaking it down into smaller, more manageable pieces.
2. Use Consistent Naming Conventions
Use descriptive names for your components. Component names should be in PascalCase (e.g., UserProfile, NavigationHeader).
3. Optimize Performance with React.memo
Use React.memo to prevent unnecessary re-renders of functional components.
import React from 'react';
import { Text } from 'react-native';
const ExpensiveComponent = React.memo(({ data }) => {
  console.log('Rendering ExpensiveComponent');
  return <Text>{data}</Text>;
});
export default ExpensiveComponent;
4. Separate Logic from UI
Keep your component logic separate from your UI rendering. This makes your code more maintainable and testable.
5. Avoid Deeply Nested Components
Deep component nesting can make your code hard to follow and debug. Try to keep your component hierarchy relatively flat.
Summary
In this chapter, we’ve explored:
- What React Native components are and their types
- Core components provided by React Native, including View, Text, Image, and more
- How to create custom components
- Component composition techniques
- Platform-specific components
- Best practices for creating and managing components
Components are the building blocks of React Native applications. Understanding how to use and combine them effectively is crucial for creating robust, maintainable, and performant mobile applications. As you continue your React Native journey, you’ll discover more advanced component patterns and techniques.
Exercises
- Create a simple counter app using functional components and the useState hook.
- Build a custom button component that accepts props for customization.
- Create a card component that displays an image, title, and description.
- Build a form with TextInput components and validation.
- Create a platform-specific component that displays differently on iOS and Android.
In the next chapter, we’ll dive deeper into state and props in React Native, which will allow you to create dynamic and interactive components.
Related Articles:
- React Native vs Flutter in 2024: A Detailed Comparison
- Top 10 React Native Libraries You Must Know in 2024
- React vs React Native: A Deep Dive into Key Differences
- How to Set Up Navigation in React Native : Step-by-Step Guide
- What is Axios? Fetch vs Axios: What’s the Difference?
- React Native Environment Setup: A Beginner’s Step-by-Step Guide
- React Native Web: A Step-by-Step Guide to Cross-Platform Development