DEV Community

Aneeqa Khan
Aneeqa Khan

Posted on

How to Create a Dropdown from Scratch in React Native

Dropdown menus are essential UI components that allow users to select one option from a list. In React Native, dropdowns can be implemented in various ways, depending on the design and user experience requirements. Here, we’ll explore two approaches to creating dropdowns from scratch:

  • Using a Modal to display the dropdown.
  • Inline display of the dropdown below a button or text field.

Prerequisites

Before starting, ensure you have React Native set up in your project. You can install React Native using:

npx react-native init MyApp
Enter fullscreen mode Exit fullscreen mode

Approach 1: Dropdown Using a Modal

The modal approach is useful in cases where you want the dropdown to take up the full screen or focus the user’s attention on the options.

Steps:

  • Create a Dropdown component that toggles a modal.
  • Render dropdown options inside the modal.
  • Pass the selected value back to the parent.

Code:

import React, { useState } from "react";
import {
  View,
  Text,
  Modal,
  TouchableOpacity,
  FlatList,
  StyleSheet,
} from "react-native";

const ModalDropdown = ({ data, onSelect }) => {
  const [isModalVisible, setModalVisible] = useState(false);
  const [selectedValue, setSelectedValue] = useState(null);

  const toggleModal = () => setModalVisible(!isModalVisible);

  const handleSelect = (item) => {
    setSelectedValue(item);
    onSelect(item);
    toggleModal();
  };

  return (
    <View style={styles.container}>
      <TouchableOpacity style={styles.button} onPress={toggleModal}>
        <Text style={styles.buttonText}>
          {selectedValue || "Select an option"}
        </Text>
      </TouchableOpacity>

      <Modal visible={isModalVisible} transparent animationType="slide">
        <View style={styles.modalBackground}>
          <View style={styles.modalContent}>
            <FlatList
              data={data}
              keyExtractor={(item, index) => index.toString()}
              renderItem={({ item }) => (
                <TouchableOpacity
                  style={styles.option}
                  onPress={() => handleSelect(item)}
                >
                  <Text style={styles.optionText}>{item}</Text>
                </TouchableOpacity>
              )}
            />
            <TouchableOpacity style={styles.closeButton} onPress={toggleModal}>
              <Text style={styles.closeText}>Close</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    margin: 20,
  },
  button: {
    padding: 15,
    backgroundColor: "#3498db",
    borderRadius: 5,
  },
  buttonText: {
    color: "white",
    textAlign: "center",
  },
  modalBackground: {
    flex: 1,
    backgroundColor: "rgba(0, 0, 0, 0.5)",
    justifyContent: "center",
    alignItems: "center",
  },
  modalContent: {
    width: "80%",
    backgroundColor: "white",
    borderRadius: 10,
    padding: 20,
  },
  option: {
    padding: 15,
    borderBottomWidth: 1,
    borderBottomColor: "#ddd",
  },
  optionText: {
    fontSize: 16,
  },
  closeButton: {
    marginTop: 10,
    padding: 10,
    backgroundColor: "#e74c3c",
    borderRadius: 5,
  },
  closeText: {
    color: "white",
    textAlign: "center",
  },
});

export default ModalDropdown;
Enter fullscreen mode Exit fullscreen mode

Screenshots:

modal dropdown

modal dropdown value


Approach 2: Dropdown Displayed Inline

This design showcases the dropdown directly beneath a button or text field; it is incorporated into the screen layout very smoothly.

Steps:

  • Use a TouchableOpacity to toggle the visibility of the dropdown.
  • Dynamically position the dropdown list below the button.
  • Use FlatList to render the options.

Code:

import React, { useState } from "react";
import {
  View,
  Text,
  TouchableOpacity,
  FlatList,
  StyleSheet,
} from "react-native";

const InlineDropdown = ({ data, onSelect }) => {
  const [isDropdownVisible, setDropdownVisible] = useState(false);
  const [selectedValue, setSelectedValue] = useState(null);
  const toggleDropdown = () => setDropdownVisible(!isDropdownVisible);
  const handleSelect = (item) => {
    setSelectedValue(item);
    onSelect(item);
    setDropdownVisible(false);
  };
  return (
    <View style={styles.container}>
      <TouchableOpacity style={styles.button} onPress={toggleDropdown}>
        <Text style={styles.buttonText}>
          {selectedValue || "Select an option"}{" "}
        </Text>
      </TouchableOpacity>
      {isDropdownVisible && (
        <View style={styles.dropdown}>
          <FlatList
            data={data}
            keyExtractor={(item, index) => index.toString()}
            renderItem={({ item }) => (
              <TouchableOpacity
                style={styles.option}
                onPress={() => handleSelect(item)}
              >
                <Text style={styles.optionText}>{item}</Text>{" "}
              </TouchableOpacity>
            )}
          />
        </View>
      )}
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    margin: 20,
  },
  button: {
    padding: 15,
    backgroundColor: "#3498db",
    borderRadius: 5,
  },
  buttonText: {
    color: "white",
    textAlign: "center",
  },
  dropdown: {
    marginTop: 5,
    backgroundColor: "white",
    borderRadius: 5,
    elevation: 3,
    shadowColor: "#000",
    shadowOpacity: 0.1,
    shadowRadius: 5,
    shadowOffset: { width: 0, height: 2 },
  },
  option: {
    padding: 15,
    borderBottomWidth: 1,
    borderBottomColor: "#ddd",
  },
  optionText: {
    fontSize: 16,
  },
});

export default InlineDropdown;
Enter fullscreen mode Exit fullscreen mode

Screenshot:

inline dropdown


Comparison

dropdown comparison


Conclusion

Different use cases are suited for modal and inline dropdowns in React Native. While the modal approach is effective for scenarios requiring a focused user interaction, the inline dropdown is ideal for scenarios where a seamless, lightweight experience is desirable.

You can thus implement either of these approaches using the code above or customize them to suit your application needs.


Thank you for reading! Feel free to connect with me on LinkedIn or GitHub.

Top comments (0)