Skip to main content

Working with Layout Components

1. Using Modal Component

Property Description Default
visible Controls the visibility of the modal false
onRequestClose Callback function when the modal is requested to close null
animationType Defines the animation type: 'none', 'fade', or 'slide' 'none'

Example: Basic Modal Usage

<Modal
  visible={isVisible}
  onRequestClose={() => setIsVisible(false)}
  animationType="fade"
>
  <View style={styles.modalContent}>
    <Text>Hello from Modal!</Text>
  </View>
</Modal>
Note: The Modal component in Expo requires a View as its direct child to properly render content.
Warning: On iOS, modals do not support animationType="slide" when used in a ScrollView.

2. Using Switch Component

Property Values Description
value boolean Current state of the switch (true or false)
onValueChange (value: boolean) => void Callback function when the switch value changes
disabled boolean If true, the switch is disabled and cannot be toggled
trackColor { false: string; true: string } Color of the track when switch is off and on
thumbColor { false: string; true: string } Color of the thumb when switch is off and on

Example: Basic Switch Usage

import React, { useState } from 'react';
import { Switch } from 'expo-switch';

const MySwitch = () => {
  const [isEnabled, setIsEnabled] = useState(false);

  return (
    <Switch
      value={isEnabled}
      onValueChange={setIsEnabled}
    />
  );
};

Example: Switch with Custom Colors

import React, { useState } from 'react';
import { Switch } from 'expo-switch';

const ColoredSwitch = () => {
  const [isEnabled, setIsEnabled] = useState(false);

  return (
    <Switch
      value={isEnabled}
      onValueChange={setIsEnabled}
      trackColor={{ false: '#767577', true: '#81b0ff' }}
      thumbColor={isEnabled ? '#f5dd4b' : '#f4f3f4'}
    />
  );
};

3. Using RefreshControl

The RefreshControl component in Expo allows you to add pull-to-refresh functionality to scrollable views like ScrollView and FlatList.

Property Type Description Default
refreshing boolean Indicates whether the refresh is currently active. false
onRefresh () => void Callback function to execute when the user triggers a refresh. undefined
tintColor string Color of the refresh indicator spinner. #000
title string Title to display during refresh (iOS only). undefined
titleColor string Color of the refresh title (iOS only). #000

Example: Using RefreshControl with ScrollView

import React, { useState } from 'react';
import { ScrollView, Text, View, RefreshControl } from 'react-native';

const MyScrollView = () => {
  const [refreshing, setRefreshing] = useState(false);
  const [data, setData] = useState([1, 2, 3, 4, 5]);

  const onRefresh = () => {
    setRefreshing(true);
    // Simulate API call
    setTimeout(() => {
      setData([6, 7, 8, 9, 10]);
      setRefreshing(false);
    }, 1000);
  };

  return (
    <ScrollView
      refreshControl={
        <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
      }
    >
      {data.map((item) => (
        <View key={item}>
          <Text>{item}</Text>
        </View>
      ))}
    </ScrollView>
  );
};

export default MyScrollView;
Note: On Android, RefreshControl is only supported inside ScrollView or FlatList. On iOS, it works with any scrollable view.

4. Using KeyboardAvoidingView

KeyboardAvoidingView is a layout component that automatically adjusts the position of your content to avoid the keyboard on mobile devices. It's particularly useful in forms or chat interfaces where the keyboard might obscure input fields.

Property Description Default Values
behavior Sets the behavior of the view when the keyboard appears. padding padding, height, position
keyboardVerticalOffset Adjusts the offset of the view from the keyboard. 0 Number

Example: Basic usage of KeyboardAvoidingView

import { KeyboardAvoidingView, TextInput, View, StyleSheet } from 'react-native';\n\nconst Example = () => {\n  return (\n    <KeyboardAvoidingView \n      style={styles.container}\n      behavior="padding"\n      keyboardVerticalOffset={80}\n    >\n      <TextInput \n        style={styles.input}\n        placeholder="Type here..."\n      />\n    </KeyboardAvoidingView>\n  );\n};\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    justifyContent: 'center',\n    alignItems: 'center',\n  },\n  input: {\n    width: '80%',\n    padding: 10,\n    borderWidth: 1,\n    borderColor: '#ccc',\n    borderRadius: 5,\n  },\n});
Note: On iOS, behavior can be set to height or position for more precise adjustments, while on Android it only supports padding.
Warning: KeyboardAvoidingView does not work properly inside a ScrollView or FlatList. Consider wrapping the scrollable content in a separate view.

5. Using SafeAreaView

Example: Basic SafeAreaView Usage

<SafeAreaView style={{ flex: 1 }}>
  <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
    <Text>Content inside SafeAreaView</Text>
  </View>
</SafeAreaView>
Property Description Default
style Style object or array of styles to apply to the view undefined
children Child components to render inside the SafeAreaView undefined
Note: SafeAreaView automatically adjusts its padding based on device notches and status bars.
Warning: On Android, SafeAreaView only applies padding on devices with notches or cutouts.

6. Using StatusBar Component

Property Values Description
backgroundColor string Background color of the status bar. Supports color names and hex values.
barStyle 'default' | 'light-content' | 'dark-content' Style of the status bar text. 'default' uses system default, 'light-content' for light text, 'dark-content' for dark text.
hidden boolean Whether to hide the status bar. Default is false.
translucent boolean Whether the status bar is translucent. Default is false.

Example: Setting StatusBar Properties

<StatusBar
  backgroundColor="#3498db"
  barStyle="light-content"
  hidden={false}
  translucent={true}
/>
Note: On iOS, translucent only works when the background color is not fully opaque.
Warning: On Android, barStyle is ignored in favor of the system's theme.

7. Using VirtualizedList

The VirtualizedList component in Expo is a powerful performance-optimized list component designed to handle large lists efficiently by only rendering the items that are currently visible on screen.

Property Description Values
data Array of data to render Array
renderItem Function that renders a single item Function
keyExtractor Function to extract a unique key for each item Function
getItem Function to get an item at a specific index Function
getItemCount Function to get the total number of items Function
initialNumToRender Number of items to render initially Number
maxToRenderPerBatch Maximum number of items to render in each batch Number
windowSize Number of items to render beyond the visible area Number
onEndReached Function called when the list is scrolled to the end Function
onEndReachedThreshold Distance from the end to trigger onEndReached Number

Example: Basic VirtualizedList Usage

import React from 'react';
import { VirtualizedList } from 'react-native';

const data = Array.from({ length: 1000 }, (_, i) => ({
  id: i,
  title: `Item ${i}`,
}));

const renderItem = ({ item }) => (
  <View style={{ padding: 10, borderBottomWidth: 1 }}>
    <Text>{item.title}</Text>
  </View>
);

const VirtualizedListExample = () => (
  <VirtualizedList
    data={data}
    renderItem={renderItem}
    keyExtractor={(item) => item.id.toString()}
    getItemCount={() => data.length}
    getItem={(data, index) => data[index]}
  />
);
Note: VirtualizedList is a low-level component and should be used with caution. For most use cases, FlatList or SectionList is preferred as they provide a simpler API and better defaults.

8. Using Animated.View

Animated.View is a core component in Expo's animation system, allowing you to animate native properties of views using declarative animations. It provides a way to create fluid, performant animations by leveraging the native animation engine.

Property Description Values
animatedStyle Applies animated styles to the view. Animated.StyleProp
useNativeDriver Enables native driver for performance. true or false
delay Delay before starting the animation. number

Example: Basic Animated View

import React, { useRef } from 'react';
import { Animated, View } from 'react-native';

const AnimatedViewExample = () => {
  const fadeAnim = useRef(new Animated.Value(0)).current;

  React.useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 1000,
      useNativeDriver: true
    }).start();
  }, []);

  return (
    <Animated.View
      style={{
        opacity: fadeAnim,
        width: 100,
        height: 100,
        backgroundColor: 'blue'
      }}
    >
    </Animated.View>
  );
};

export default AnimatedViewExample;
Note: Native driver is highly recommended for better performance and smoother animations.
Warning: Not all style properties support the native driver. Ensure that only supported properties are used.

Key Points

  • Animated.View is a wrapper for View that supports animated properties.
  • Use useNativeDriver: true for optimal performance.
  • Only specific style properties (e.g., opacity, transform) are supported in native driver.

9. Using Portal Component

The Portal component in Expo allows you to render children outside the current component hierarchy, which is useful for modals, dropdowns, or any UI element that needs to escape its parent's layout constraints.

Property Description Default
children The content to render inside the portal Required
host The host component to render the portal into. If not provided, it will use the root view null

Example: Basic Portal Usage

<View style={styles.container}>
  <Portal>
    <View style={styles.modal}>
      <Text>This modal is rendered outside the container</Text>
    </View>
  </Portal>
</View>
Note: Portals are particularly useful in React Navigation or when you need to overlay content on top of other components without affecting their layout.

10. Using Fragment Component

The Fragment component in Expo (and React Native) is used to group multiple elements without adding an extra node to the DOM. It's particularly useful when building layouts where you need to return multiple elements from a component's render method.

Property Description Usage
children Content to be rendered inside the Fragment <Fragment><View /><Text /></Fragment>

Example: Basic Fragment Usage

<Fragment>
  <View style={styles.container}>
    <Text>First View</Text>
  </View>
  <View style={styles.container}>
    <Text>Second View</Text>
  </View>
</Fragment>
Note: Fragments are not supported in all environments, but they work well in Expo and React Native.

Was this article helpful?