Segmented Toggle in React Native

Last updated: June 2025
In this tutorial, we’ll walk through creating a simple and customizable segmented toggle component. This component is perfect for forms, filters, tabbed views, and more!
Here's what we're making:

- Import React Native Components
At the top of your component file (mine is SegmentToggle.tsx
), you will import the following:
import React, {useState} from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
- Define State Variables
This is where you'll define the selected
state variable, with values/labels associated with each side of the toggle.
const [selected, setSelected] = useState<'option 1' | 'option 2'>('option 1');
Selected can only be equal to option 1
or option 2
. One side of the toggle will always be selected.
- Component and Styles
Now we are ready to start building out our segmented toggle. We'll start with the left side of the toggle.
First we are going to add a View
and add styles.container
<View style={styles.container}>
// ...
</View>
styles.container
:
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
},
})
Explanation
flexDirection: 'row',
: aligns both sides of the toggle next to each other (instead of stacking them vertically)
Next, we will create the left side (segment) of the toggle:
- We will add a
TouchableOpacity
to handle the left side of the toggle being selected:
//...
<TouchableOpacity
style={[
styles.segment,
selected === 'option 1'
? styles.selectedSegment
: styles.unselectedSegment,
styles.leftSegment,
]}
onPress={() => setSelected('option 1')}>
// ...
</TouchableOpacity>
selected === 'option 1' ? styles.selectedSegment : styles.unselectedSegment
: sets the style based on whether or not this side is selected using theselected
state variablestyles.leftSegment
: gives left side specific stylingonPress={() => setSelected('option 1')}
: sets theselected
variable tooption 1
and deselectsoption 2
when the left side of the toggle is pressed
styles.segment
Each side of the toggle has three styles applied: one for layout (segment
), one for selection state (selectedSegment
/ unselectedSegment
), and one for shape (leftSegment
/ rightSegment
).”
segment: {
paddingVertical: 10,
paddingHorizontal: 25,
flex: 1,
alignItems: 'center',
},
selectedSegment: {
backgroundColor: '#9E9E9E',
},
unselectedSegment: {
backgroundColor: '#EEEEEE',
},
leftSegment: {
borderTopLeftRadius: 40,
borderBottomLeftRadius: 40,
},
segment
: gives the segment some horizontal and vertical spacing, allows it to use up all of the available space designated for it (flex: 1
), and centers it within the segmentselectedSegment
: background color for the selected segment sideunselectedSegment
: background color for the unselected segment sideleftSegment
: rounds the top left and bottom left corners while keeping the top right and bottom right the same
At this point the toggle looks like this:

- Segment
Text
:
Now we will add the text to the left side of the toggle:
Text
<TouchableOpacity //...>
<Text
style={
selected === 'option 1' ? styles.selectedText : styles.unselectedText
}>
Option 1
</Text>
</TouchableOpacity>
The Text
style is determined by the selected
variable. Just like above with the TouchableOpacity
, the text will appear slightly different depending on if it's side of the segment is selected or not.
Styles:
selectedText: {
fontWeight: '600',
color: 'black',
},
unselectedText: {
color: 'black',
opacity: 0.7,
},
selectedText
: bold, black textunselectedText
: still black text but slightly transparent
Now the toggle looks like this:

To add the right side, we will just add another TouchableOpacity
and Text
components and the corresponding styles for the right side:
<TouchableOpacity
style={[
styles.segment,
selected === 'option 2'
? styles.selectedSegment
: styles.unselectedSegment,
styles.rightSegment,
]}
onPress={() => setSelected('option 2')}>
<Text
style={
selected === 'option 2' ? styles.selectedText : styles.unselectedText
}>
Option 2
</Text>
</TouchableOpacity>
This is the same code as above but with a few tweaks:
option 2
replacesoptions 1
rightSegment
is used instead ofleftSegment
rightSegment
All we need to add now is a style for the right side segment:
rightSegment: {
borderTopRightRadius: 40,
borderBottomRightRadius: 40,
},
- Same as
leftSegment
except it rounds out the top right and bottom right corners instead of the left side corners (this creates a "pill" shape)

Complete Component File
Here is the complete component:
import React, { useState } from "react";
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
const SegmentToggle = () => {
const [selected, setSelected] = useState<"option 1" | "option 2">("option 1");
return (
<View style={styles.container}>
<TouchableOpacity
style={[
styles.segment,
selected === "option 1"
? styles.selectedSegment
: styles.unselectedSegment,
styles.leftSegment,
]}
onPress={() => setSelected("option 1")}
>
<Text
style={
selected === "option 1"
? styles.selectedText
: styles.unselectedText
}
>
Option 1
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.segment,
selected === "option 2"
? styles.selectedSegment
: styles.unselectedSegment,
styles.rightSegment,
]}
onPress={() => setSelected("option 2")}
>
<Text
style={
selected === "option 2"
? styles.selectedText
: styles.unselectedText
}
>
Option 2
</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: "row",
},
segment: {
paddingVertical: 10,
paddingHorizontal: 25,
flex: 1,
alignItems: "center",
},
selectedSegment: {
backgroundColor: "#9E9E9E",
},
unselectedSegment: {
backgroundColor: "#EEEEEE",
},
selectedText: {
fontWeight: "600",
color: "black",
},
unselectedText: {
color: "#000",
opacity: 0.7,
},
leftSegment: {
borderTopLeftRadius: 40,
borderBottomLeftRadius: 40,
},
rightSegment: {
borderTopRightRadius: 40,
borderBottomRightRadius: 40,
},
});
export default SegmentToggle;