Building React Native Collapsible Accordions

Master the art of creating smooth, accessible accordion components using FlatList, Animated API, and Reanimated for production-ready mobile interfaces.

What Are Accordion Components?

An accordion in React Native consists of header sections that users can tap to reveal or hide associated content panels. This pattern appears frequently in FAQ sections, settings screens, product detail pages, and anywhere hierarchical content needs to be presented without overwhelming the interface. The terminology varies across platforms: Material Design called them "Expansion Panels," Apple's Human Interface Guidelines refers to them as "Disclosure controls," and SwiftUI uses "DisclosureGroup" (Whacky Labs).

The core mechanics of an accordion involve tracking the expanded/collapsed state of each section and animating the transition between these states. React Native provides several ways to implement this functionality, ranging from basic conditional rendering with React hooks to advanced animations with the Reanimated library. Choosing the right approach depends on your specific requirements for animation smoothness, library dependencies, and the complexity of your content structure (LogRocket).

Core Components Needed

Building an accordion requires understanding several React Native components that work together:

  • TouchableOpacity/Pressable - Handles user interactions on section headers
  • View and Text - Structures the visual layout
  • FlatList - Provides efficient rendering for multiple sections
  • Animated API / Reanimated - Manages smooth transitions between states

For mobile applications requiring sophisticated UI patterns, our mobile app development services can help you implement production-ready components with proper architecture and performance optimization.

Approach 1: Simple State-Based Accordion with FlatList

The most straightforward approach to building an accordion uses React's useState hook to manage expansion state and conditional rendering to show or hide content. This method requires no external libraries and works well for simple use cases with basic animation needs (GeeksforGeeks).

Basic Implementation Structure

The implementation centers on creating a list where each item maintains its own expanded state. Using FlatList provides performance benefits for longer lists by only rendering visible items. Each list item contains a header (always visible) and a body (conditionally rendered based on state). The toggle function switches the expanded state when the header is pressed.

The data structure typically includes an id, title for the header, and content for the expandable section. The expanded state can be managed as either a single index (allowing only one section open at a time) or an array of indices (allowing multiple sections to remain open simultaneously). The single-index approach creates a more focused experience, while the multiple-index approach provides easier comparison of related content (LogRocket).

Basic FlatList Accordion Implementation
1import React, { useState } from 'react';2import { View, Text, TouchableOpacity, FlatList, StyleSheet } from 'react-native';3 4const ExpandableListItem = ({ item }) => {5 const [expanded, setExpanded] = useState(false);6 7 const toggleExpand = () => {8 setExpanded(!expanded);9 };10 11 return (12 <View style={styles.itemContainer}>13 <TouchableOpacity14 onPress={toggleExpand}15 style={styles.itemTouchable}16 >17 <Text style={styles.itemTitle}>{item.title}</Text>18 </TouchableOpacity>19 {expanded && (20 <Text style={styles.itemContent}>{item.content}</Text>21 )}22 </View>23 );24};25 26const ExpandableList = ({ data }) => {27 const renderItem = ({ item }) => (28 <ExpandableListItem item={item} />29 );30 31 return (32 <FlatList33 data={data}34 renderItem={renderItem}35 keyExtractor={(item) => item.id.toString()}36 />37 );38};

State Management Patterns

Single Selection Mode

Single selection mode ensures only one accordion section is expanded at a time, creating a focused user experience where expanding one section automatically collapses others:

const [expandedIndex, setExpandedIndex] = useState(null);

const toggleSection = (index) => {
 setExpandedIndex(expandedIndex === index ? null : index);
};

This pattern is particularly effective for FAQ-style content where users need to concentrate on one answer at a time (GeeksforGeeks).

Multiple Selection Mode

Multiple selection allows several sections to remain expanded simultaneously, which suits comparison scenarios or settings pages where users may need to reference multiple sections simultaneously:

const [expandedItems, setExpandedItems] = useState(new Set());

const toggleSection = (index) => {
 const newExpanded = new Set(expandedItems);
 if (newExpanded.has(index)) {
 newExpanded.delete(index);
 } else {
 newExpanded.add(index);
 }
 setExpandedItems(newExpanded);
};

This approach provides flexibility for users who need to compare content across different sections, making it ideal for settings screens and feature comparisons (LogRocket).

For applications requiring complex state management across multiple component types, our React Native development services can help you architect scalable state solutions.

Approach 2: Animated Accordions with React Native's Built-in Animated API

For smoother user experiences, React Native's Animated API provides transition effects without requiring external dependencies. This approach animates properties like height, opacity, or scale to create fluid expand and collapse transitions (LogRocket).

Implementing Animated Height Transitions

The Animated API works by creating animated values that can be interpolated to produce smooth transitions. For accordion animations, you'll animate the height property from zero to the content's measured height. This requires using the onLayout callback to dynamically measure content height before animation begins (Whacky Labs).

Since React Native cannot animate to "auto" height, we first render the content invisibly to measure its natural height, then animate between zero and that measured value. The overflow: 'hidden' property ensures content remains clipped during animation.

LayoutAnimation for Automatic Layout Transitions

React Native's LayoutAnimation provides a simpler alternative for animating layout changes. When state changes cause the layout to recalculate, LayoutAnimation automatically animates the transition:

import { LayoutAnimation, Platform, UIManager } from 'react-native';

// Enable LayoutAnimation on Android
if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
 UIManager.setLayoutAnimationEnabledExperimental(true);
}

const toggleItem = () => {
 LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
 setExpanded(!expanded);
};

LayoutAnimation automatically handles the interpolation between old and new layout states, making it ideal for simple expand/collapse effects. However, it provides less control than the Animated API and may not achieve the same level of smoothness for complex animations (LogRocket).

For teams implementing advanced animation patterns, our animation consultation services can help optimize performance and user experience across your mobile applications.

Approach 3: Reanimated-Based Advanced Accordions

For production applications requiring buttery-smooth animations, the Reanimated library from Software Mansion provides a more powerful animation framework. Reanimated runs animations on the UI thread, eliminating the jank often seen with JavaScript-based animations on complex interfaces (LogRocket).

Setup Reanimated

npm install react-native-reanimated

Then add the Reanimated babel plugin to your babel.config.js:

module.exports = {
 presets: { ... },
 plugins: ['react-native-reanimated/plugin'],
};

Creating Smooth Animations

Reanimated's useAnimatedStyle hook creates animations that run on the UI thread, achieving smooth 60fps animations. The withTiming function provides a natural easing curve, and the absolute positioning with onLayout measurement ensures content height is calculated accurately before animation begins (Whacky Labs).

Our AI-powered application development services can help you integrate intelligent features alongside smooth UI animations for next-generation mobile experiences.

Reanimated Accordion Implementation
1import Animated, { useAnimatedStyle, withTiming, useState } from 'react-native-reanimated';2 3const AccordionItem = ({ title, content, isExpanded }) => {4 const [maxHeight, setMaxHeight] = useState(0);5 6 const containerStyle = useAnimatedStyle(() => {7 return {8 height: isExpanded ? withTiming(maxHeight) : withTiming(0),9 };10 });11 12 return (13 <Animated.View style={[containerStyle, { overflow: 'hidden' }]}>14 <View15 style={{ position: 'absolute' }}16 onLayout={(e) => {17 if (maxHeight === 0) {18 setMaxHeight(e.nativeEvent.layout.height);19 }20 }}21 >22 <Text>{content}</Text>23 </View>24 </Animated.View>25 );26};

Community Libraries for Accordions

react-native-collapsible

The react-native-collapsible library provides a straightforward implementation with minimal boilerplate, handling the complex animation logic internally (LogRocket):

import Collapsible from 'react-native-collapsible';

<Collapsible collapsed={isCollapsed}>
 <Text>Hidden content goes here</Text>
</Collapsible>

This library is ideal for rapid development but adds a dependency and may not offer the same level of customization as custom implementations.

React Native Paper

For applications already using Material Design components, React Native Paper's Accordion component provides consistent styling and accessibility (LogRocket):

import { Accordion } from 'react-native-paper';

<Accordion.Group>
 <Accordion.Item title="Section 1">
 <Accordion.Content>Content for section 1</Accordion.Content>
 </Accordion.Item>
 <Accordion.Item title="Section 2">
 <Accordion.Content>Content for section 2</Accordion.Content>
 </Accordion.Item>
</Accordion.Group>

React Native Paper handles accessibility automatically, including proper ARIA attributes and keyboard navigation for iOS.

When building component libraries for enterprise applications, our custom software development services can help you establish sustainable component architecture and documentation practices.

Performance Optimization Techniques

Virtualization and List Rendering

When working with long accordion lists, proper virtualization prevents memory issues (GeeksforGeeks):

<FlatList
 data={sections}
 renderItem={renderItem}
 keyExtractor={(item) => item.id}
 removeClippedSubviews={true}
 maxToRenderPerBatch={10}
 windowSize={10}
/>

These FlatList optimization props ensure only visible items are rendered, and new items are rendered in batches to maintain smooth scrolling during rapid list navigation.

Memoization

Prevent unnecessary re-renders with React.memo and useCallback (LogRocket):

const AccordionSection = React.memo(({ section, isExpanded, onToggle }) => {
 return (
 <TouchableOpacity onPress={() => onToggle(section.id)}>
 <Text>{section.title}</Text>
 {isExpanded && <Text>{section.content}</Text>}
 </TouchableOpacity>
 );
});

const renderSection = useCallback(({ item }) => (
 <AccordionSection section={item} />
), []);

Memoization becomes increasingly important as accordion lists grow, ensuring that expanding one section doesn't trigger re-renders of all other sections.

Animation Performance

For smooth animations, always use the shared value approach with Reanimated and avoid animations that trigger JavaScript thread work:

// Good: UI thread animation
const style = useAnimatedStyle(() => ({
 height: withTiming(isExpanded ? 100 : 0),
}));

To learn more about optimizing React Native performance, explore our comprehensive React Native development resources.

Accessibility Considerations

Ensure accordion sections are accessible to screen reader users (LogRocket):

<TouchableOpacity
 accessible={true}
 accessibilityRole="button"
 accessibilityLabel={`${title}, ${isExpanded ? 'expanded' : 'collapsed'}`}
 accessibilityControls={`content-${id}`}
>
 <Text>{title}</Text>
</TouchableOpacity>

<View accessibilityViewIsModal={true}>
 <Text accessibilityLiveRegion="polite">{content}</Text>
</View>

Key Accessibility Attributes

AttributePurpose
accessibilityRole="button"Announces tap target as interactive
accessibilityLabelProvides context about section state
accessibilityControlsCreates relationship between header and content
accessibilityLiveRegionAnnounces content changes to screen readers

The accessibilityRole="button" announces the tap target as interactive, while accessibilityLabel provides context about the section's state. accessibilityControls creates the relationship between the header and its content panel.

Keyboard Navigation

On platforms supporting keyboard interaction, ensure headers respond to enter/space key presses. Pressable handles keyboard activation automatically (LogRocket):

<Pressable
 onPress={toggleSection}
 accessibilityRole="button"
>
 <Text>{title}</Text>
</Pressable>

Testing with accessibility tools ensures your accordion works for all users, regardless of how they interact with the application.

Building inclusive mobile experiences is a core principle of our accessibility-focused development approach.

Common Use Cases

FAQ Sections

FAQ accordions organize frequently asked questions with expandable answers. FAQ sections benefit from single-selection mode, allowing users to focus on one answer at a time while keeping the interface uncluttered (GeeksforGeeks).

Settings Screens

Settings screens often use accordions to group related preferences. Settings screens typically use multiple-selection mode, allowing users to view multiple categories simultaneously (LogRocket).

Product Detail Pages

E-commerce applications use accordions for product specifications, helping reduce page length while keeping information accessible (LogRocket).

Best Practices and Recommendations

Animation Guidelines

Effective accordion animations follow specific principles for optimal user experience. Keep expansion animations between 200-400 milliseconds for a responsive feel without feeling rushed. Use easing functions that slow at the end, such as easeInEaseOut, to indicate when the animation completes. Never animate properties that trigger layout calculations during the animation, as this causes visual jank (Whacky Labs).

Visual Feedback

Users should receive clear feedback when interacting with accordion sections. Consider adding icon rotation animations that indicate expand/collapse state, subtle background color changes on header press, and spacing adjustments that accommodate expanding content without jarring jumps (LogRocket).

Testing Across Devices

Test accordion implementations on various screen sizes and OS versions. Android and iOS may render animations differently, and older devices may struggle with complex multi-animation sequences. Consider providing reduced-motion alternatives for users who prefer less animation (LogRocket).

For organizations building React Native applications at scale, our custom software development services can help establish component libraries and design systems that ensure consistency across your mobile applications.

Frequently Asked Questions

Ready to Build Better React Native Interfaces?

Our team of React Native experts can help you create smooth, accessible accordion components and other mobile UI patterns for your application.

Sources

  1. LogRocket: Options for building React Native collapsible accordions - Comprehensive comparison of accordion implementation approaches in React Native
  2. GeeksforGeeks: Create an Expandable ListView in React Native - Beginner-friendly FlatList-based accordion implementation
  3. Whacky Labs: How to make an accordion with React Native - Reanimated-based animated accordion implementation
  4. React Native Reanimated Documentation - Official Reanimated documentation for accordion patterns
  5. Apple Human Interface Guidelines: Disclosure Controls - Apple's official accessibility guidelines