Home / Articles

Building a Configurable Select Component for React Native Paper

A walkthrough of designing and open-sourcing react-native-paper-select, covering search, multi-select chips, sectioned lists, and performance tradeoffs.

Publisher: REACTAPP.TOP12 min read2663 words

This article is published in English.

Sources: I Built a React Native Select Component — and Turned It Into an Open-Source Package: `react-native-paper-select`

Building a real dropdown in React Native is almost never as simple as it sounds

If you've spent time trying to implement a proper dropdown in React Native, you already know that "just a dropdown" quickly turns into a much bigger task.

You end up needing to manage selection state, wire up search, support multiple selections, handle long lists, present the UI in a way that feels native on mobile, add validation, and make sure the whole thing visually fits into the rest of your app.

If your project is already built on top of React Native Paper, pulling in a separate UI library just to get a working select field feels like overkill.

That mismatch is the exact problem this component was created to address.

The goal was a reusable select component that felt at home inside React Native Paper, worked for both single and multiple selection, and spared every project from rebuilding the same interaction pattern over and over.

So it got built from scratch.

What began as a fairly narrow UI component eventually grew into react-native-paper-select — an open-source React Native package that now includes search, multi-select, chip-based display, sectioned lists, radio-button selection, bottom sheets, menus, and performance-conscious list rendering.

This article covers the motivation behind building it, how the component changed over time, the engineering choices that shaped it, and the lessons learned while turning something originally built for one app into a general-purpose open-source library.

The Problem

On the surface, dropdowns seem trivial.

Once you actually start implementing one, though, a long list of design questions shows up:

  • How do you display the currently selected value?
  • Does the field need to support one selection, or several?
  • What's the right presentation for the list of choices?
  • How should search work inside that list?
  • Should behavior differ between Android and iOS?
  • How do you render very long lists without hurting performance?
  • How do you keep the developer-facing API simple?
  • How do you allow customization without turning the component into something complicated to use?

Solving these questions from scratch inside every individual app didn't make sense.

Rather than building another one-off, app-specific component, it made more sense to design something reusable from the start.

The underlying idea was simple:

Build a select component on top of React Native Paper's own UI primitives, and make it easy enough that other React Native developers would actually want to use it.

Introducing react-native-paper-select

react-native-paper-select is a configurable component for React Native that supports both single-select and multi-select use cases.

The first version leaned on familiar building blocks already provided by React Native Paper, including:

  • TextInput
  • Checkbox
  • Dialog

The intent was to give developers a selection experience that felt visually and behaviorally consistent with apps already built around React Native Paper's design system.

As the package matured, it moved past that initial implementation to support additional presentation styles and richer selection behavior.

Installing the Package

Getting up and running takes only a couple of steps.

npm install react-native-paper-select

Or, if you prefer Yarn:

yarn add react-native-paper-select

Once installed, import the component like this:

import { PaperSelect } from 'react-native-paper-select';

A Basic Select

To create a minimal select field, you just need a list of options and a function to handle the selection.

Here's an example:

const [selected, setSelected] = useState({
  value: '',
  label: '',
});
const options = [
  {
    _id: '1',
    value: 'React Native',
  },
  {
    _id: '2',
    value: 'Flutter',
  },
  {
    _id: '3',
    value: 'Native Android',
  },
];

And then rendering the component:

<PaperSelect
  label="Framework"
  value={selected.label}
  onSelection={(value) => setSelected(value)}
  arrayList={options}
  selectedArrayList={selected}
/>

What matters here isn't how little code this takes.

It's what that code hides.

From the application's point of view, there are really only two questions to answer:

What options are available?

and

What did the user pick?

Everything related to presentation and interaction is handled internally by the component itself.

Single Select vs Multi Select

Supporting both single-selection and multi-selection from the start was one of the defining requirements for this component.

Single-select is fairly simple to reason about:

Select Framework
----------------
○ React Native
○ Flutter
○ Native Android

Multi-select, however, brings in additional state to manage:

Select Technologies
-------------------
☑ React Native
☑ TypeScript
☐ Flutter
☑ Node.js

That means the component has to take care of:

  1. Tracking selection state
  2. Handling deselection
  3. Showing multiple selected values at once
  4. Returning the updated set of selections
  5. Keeping the displayed UI in sync with the underlying data

The intention was to contain all of that complexity within the component itself, rather than pushing it onto every developer using the package.

Why React Native Paper?

Since the surrounding application already relied on React Native Paper, building the select component on top of that same design system was a natural choice.

Instead of reinventing every visual element, the component could reuse UI pieces Paper already provided.

At a high level, the internal structure looked roughly like this:

                PaperSelect
                     │
          ┌──────────┴──────────┐
          │                     │
      TextInput            Selection UI
                                │
                    ┌───────────┼───────────┐
                    │           │           │
                 Checkbox      Radio       List

This design choice brings a real benefit.

Any application already using React Native Paper can drop this select component in without introducing a visual style that clashes with the rest of the interface.

From Dialog to Multiple Presentation Styles

The earliest iteration of the component only offered a dialog for making a selection.

The interaction worked like this:

TextInput
    ↓
User taps field
    ↓
Dialog opens
    ↓
User selects an item
    ↓
Selected value appears in TextInput

As the component matured, though, it became obvious that a dialog isn't always the right pattern for every mobile screen.

UX needs vary a lot from one app to another.

To account for that, the component grew to support several presentation modes:

  • Dialog
  • Bottom Sheet
  • Menu

With this change, the same underlying select component can be dropped into very different interaction contexts, and developers don't have to rewrite their integration to switch between them.

For instance:

<PaperSelect
  presentationStyle="bottomSheet"
  ...
/>

This flexibility marked a meaningful step forward for the library.

The selection logic stays identical no matter which style is chosen — only how it's presented to the user changes.

Handling Large Lists

A less obvious challenge with dropdown-style components is how well the list performs as it grows.

Picture a select component with:

10 items

That's trivial to render.

Now picture one with:

1,000 items

or even:

10,000 items

Rendering that many list items all at once can start to hurt the responsiveness of a mobile app.

To avoid that, the package relies on FlashList for rendering its option lists.

The concept is straightforward:

Large dataset
      ↓
Virtualized list
      ↓
Render what is needed
      ↓
Better scrolling performance

Performance isn't a concern you can defer until you're building something large-scale.

Any component meant for reuse has to be built with scale in mind from the start, since you rarely know in advance how big the datasets passed into it will be.

As the number of selectable options increases, search becomes essential.

Rather than making users scroll endlessly through a long list, the component offers a searchable way to narrow down choices.

The flow looks like this:

Search
  ↓
Filter options
  ↓
Select result
  ↓
Update selection

It might seem like a minor addition from a user's point of view, but it has a big impact on usability once the dataset grows past a handful of items.

Multi-Select With Chips

Showing several selected values at once can get cluttered fast.

For example, a value like:

React Native, TypeScript, Node.js, MongoDB

is hard to parse when crammed into a standard text input.

Chips solve that problem.

Selected values can instead be rendered as separate, distinct blocks:

[ React Native ] [ TypeScript ]
[ Node.js ]      [ MongoDB ]

The component supports this chip-based display for multi-select scenarios, giving users a much clearer picture of what they've chosen.

It also makes removing individual selections far more intuitive.

Sectional Lists

Another requirement that came up was the ability to group related options together.

Instead of one long, flat list like:

React
Angular
Vue
Node.js
Java
Python
MongoDB
PostgreSQL

options can be organized under headings:

Frontend
☐ React
☐ Angular
☐ Vue
Backend☐ Node.js
☐ Java
☐ Python
Database☐ MongoDB
☐ PostgreSQL

Grouping this way makes large option sets much easier to scan and understand.

In multi-select mode, letting users select an entire section at once speeds things up considerably.

For example:

☑ Frontend
    ☑ React
    ☑ Angular
    ☑ Vue

This beats forcing someone to tap through every item one at a time.

Radio Buttons for Single Selection

Checkboxes make sense when more than one option can be picked.

But for single-selection scenarios, radio buttons communicate the intent more clearly to the user.

That's why the package also offers a radio-button variant of the selection UI.

The core idea underneath stays consistent:

Options
   ↓
User chooses one
   ↓
Selection state updated

Only the visual presentation shifts.

This highlights an important principle for building reusable components:

Keep the selection logic separate from how that selection gets displayed.

TypeScript and API Design

Since this is meant to be used by other developers, the shape of the API matters just as much as how the UI looks.

Someone consuming the package shouldn't need to know anything about how it works internally.

Ideally, they can reason about it purely in terms of:

Input
  ↓
Options
  ↓
User interaction
  ↓
Selection
  ↓
Callback

instead of:

Dialog state
Modal state
List state
Search state
Checkbox state
Rendering state
...

A well-designed component API hides that internal complexity from the consumer.

That's one of the clearer lessons that came out of building and iterating on this package.

Open Source Changes the Way You Build

Writing a component for your own app is a different exercise than writing one for a wider audience of developers.

Inside a single application, the bar can be:

"This solves my specific case."

Once it's open source, the question shifts to:

"Would this API make sense to a developer who has never looked at the source code?"

That shift changes your priorities as you build.

Suddenly you're paying much closer attention to things like:

  • Consistency across the API
  • Documentation
  • Backward compatibility
  • Edge cases
  • Sensible defaults
  • Type definitions
  • Customization options
  • Performance
  • Versioning

What starts out as a small, simple component can turn into something surprisingly intricate once other developers start relying on it in production.

How the Project Progressed Over Time

What began as a straightforward select component slowly turned into a more comprehensive selection toolkit.

You could roughly map out its growth like this:

Simple Select
      ↓
Single Selection
      ↓
Multi Selection
      ↓
    Search
      ↓
Large List Handling
      ↓
    Chips
      ↓
   Sections
      ↓
Radio Selection
      ↓
Bottom Sheet
      ↓
Menu Presentation

Each new capability addressed a genuine pain point around usability or developer experience.

That's one of the aspects of building in the open that stands out.

When you ship version 1, you rarely have a clear picture of what the finished library will eventually look like.

Instead, the package keeps shifting shape as real-world requirements, user feedback, and new use cases surface.

Lessons From the Process

1. Minor pain points can grow into worthwhile open-source projects

The initial issue wasn't groundbreaking in any way.

A reusable select component was simply missing.

But there's a real gap between fixing something for your own use and refining it to the point where other people can pick it up and use it too.

Sometimes that gap is exactly wide enough to justify starting an open-source project.

2. Making something reusable means abstracting it properly

A well-designed component shouldn't be welded to the specific app that gave birth to it.

Instead, it needs to present a clean, simple interface on the outside while tucking its internal complexity out of view.

That principle applies well beyond the world of React Native.

3. Component design is also about the user experience

Making a component reusable at the code level isn't the whole story.

How it feels to interact with matters just as much.

Dialogs, bottom sheets, menus, chips, search fields, radio buttons, and sectioned lists are all just different answers to the same core question:

What's the best way for someone to make a selection?

4. Reusable components need to be built with performance in mind

A component that works fine with ten items might later be used somewhere with ten thousand.

That's exactly why decisions about list rendering and virtualization belong at the design stage, not as an afterthought once performance issues start showing up in production.

5. Documentation is a core part of the package, not an extra

Code that works isn't enough to call a package finished.

Developers still need clear answers about:

  • How to install it
  • How to use it
  • Which props are exposed
  • What shape the expected data should take
  • How to customize its behavior and appearance
  • Which features are actually supported

Solid documentation is what closes the gap between someone thinking:

"I found this package."

and reaching the point where they can confidently say:

"I can use this package."

Where the Project Goes From Here

The goal behind react-native-paper-select was modest at the outset: a select component that would fit naturally into apps already using React Native Paper.

Since then it has matured into a much more capable piece of the puzzle, now covering multiple selection modes, several presentation styles, search, chip-based selection, sectioned data, and performance-conscious list rendering.

There's still plenty of room to keep improving it.

No open-source project is ever truly done.

New devices keep appearing, React Native itself keeps releasing updates, design expectations shift, accessibility needs evolve, performance considerations resurface, and developers keep sending in feedback worth acting on.

That ongoing evolution is part of what makes maintaining a library like this genuinely engaging.

Closing Thoughts

Working on react-native-paper-select showed that an open-source project doesn't need to start from a grand vision.

Often it starts with a small, specific problem you run into while building something else.

You fix it for yourself.

Then it becomes clear the fix could help others facing the same problem.

So you refine it.

You write it up properly.

You put it out there.

And over time, a small internal component can turn into a package that other developers rely on for their own projects.

That's the story behind react-native-paper-select.

If your project uses React Native Paper and you need a flexible select or multi-select component, the repository is hosted on GitHub, and the package itself is published on npm.

Feedback, bug reports, and contributions are always welcome if you end up using the package.