React NativeExamples · Props · Code

Number Picker in React Native

There’s no built-in number picker in React Native. The two clean options are a stepper (a −/+ control, dependency-free) for small ranges, or the native @react-native-picker/pickerwheel for longer ranges. Here’s both.

What is a number picker?

A number picker lets the user choose a numeric value — a quantity, an age, a rating. For a handful of values (1–10), a stepper is faster to use and needs no library. For a wide range (a year, a weight), a scroll wheel via the native Picker is better.

Stepper (no dependencies)

Best for small ranges like a cart quantity. Clamp to min/max and disable at the bounds:

import { useState } from 'react';
import { Pressable, Text, View } from 'react-native';

function NumberStepper({ value, onChange, min = 0, max = 99, step = 1 }) {
  const clamp = (n) => Math.min(max, Math.max(min, n));

  return (
    <View style={{ flexDirection: 'row', alignItems: 'center', gap: 16 }}>
      <Pressable
        onPress={() => onChange(clamp(value - step))}
        disabled={value <= min}
        style={{ width: 44, height: 44, borderRadius: 22, backgroundColor: '#f3f4f6', alignItems: 'center', justifyContent: 'center' }}
      >
        <Text style={{ fontSize: 22 }}>−</Text>
      </Pressable>

      <Text style={{ fontSize: 20, minWidth: 40, textAlign: 'center' }}>{value}</Text>

      <Pressable
        onPress={() => onChange(clamp(value + step))}
        disabled={value >= max}
        style={{ width: 44, height: 44, borderRadius: 22, backgroundColor: '#f3f4f6', alignItems: 'center', justifyContent: 'center' }}
      >
        <Text style={{ fontSize: 22 }}>+</Text>
      </Pressable>
    </View>
  );
}

Wheel (native Picker)

Generate the range as Picker items for a native scroll wheel:

// npx expo install @react-native-picker/picker
import { Picker } from '@react-native-picker/picker';
import { useState } from 'react';

function NumberWheel({ from = 1, to = 10 }) {
  const [value, setValue] = useState(from);
  const numbers = Array.from({ length: to - from + 1 }, (_, i) => from + i);

  return (
    <Picker selectedValue={value} onValueChange={setValue}>
      {numbers.map((n) => (
        <Picker.Item key={n} label={String(n)} value={n} />
      ))}
    </Picker>
  );
}

Props (stepper)

PropTypeDefaultDescription
valuenumberCurrent value (controlled).
onChangefn(number)Called with the new clamped value.
minnumber0Lower bound; the − button disables here.
maxnumber99Upper bound; the + button disables here.
stepnumber1Increment per tap.

Gotchas

  • Always clamp with Math.min/Math.max — without it, holding a button pushes the value past your range.
  • Disable the buttons at the bounds (disabled={value <= min}) so users get feedback instead of a dead tap.
  • The native Picker renders very differently on iOS (inline wheel) vs Android (dropdown/dialog). Test both before shipping.
  • For a long range, don’t build thousands of Picker.Items — it’s slow. Use a stepper with a larger step, or a text input with numeric keyboard.

FAQ

Is there a number picker in React Native? Not built in. Use a stepper you build from Pressables, or the native @react-native-picker/picker for a wheel.

Stepper or wheel? Stepper for ~1–20 values; wheel for wide ranges like years or weights.

Related components

Skip the boilerplate

Describe your screen in ShipNative and it wires up the component for you — in a real, exportable React Native app.

Generate it with AI →