Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

BMI Calculator App in React Native

BMI Calculator App

~10 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

The BMI calculator is the classic "form with a calculation" app – a good example of numeric input validation, derived values, and a visual result display with category colors.

1. Description

Body Mass Index: weight (kg) / height (m)². The app takes height (in cm, converted internally) and weight as text input, converts them to numbers, computes the BMI, and assigns it to one of four WHO categories with a matching color.

2. Short example

const bmi = weightKg / (heightM * heightM);
// e.g. 70 / (1.75 * 1.75) = 22.86

3. Complete project: a BMI calculator with categories

npx create-expo-app bmi-calculator-app
cd bmi-calculator-app
utils/bmi.js
export function calculateBmi(heightCm, weightKg) {
  const heightM = heightCm / 100;
  return weightKg / (heightM * heightM);
}

export function bmiCategory(bmi) {
  if (bmi < 18.5) return { label: 'Underweight', color: '#3b82f6' };
  if (bmi < 25) return { label: 'Normal weight', color: '#16a34a' };
  if (bmi < 30) return { label: 'Overweight', color: '#f59e0b' };
  return { label: 'Obesity', color: '#dc2626' };
}
App.js
import { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, StyleSheet } from 'react-native';
import { calculateBmi, bmiCategory } from './utils/bmi';

export default function App() {
  const [height, setHeight] = useState('175');
  const [weight, setWeight] = useState('70');
  const [result, setResult] = useState(null);
  const [error, setError] = useState(null);

  function calculate() {
    const heightNumber = parseFloat(height.replace(',', '.'));
    const weightNumber = parseFloat(weight.replace(',', '.'));

    if (!heightNumber || !weightNumber || heightNumber <= 0 || weightNumber <= 0) {
      setError('Please enter valid, positive numbers.');
      setResult(null);
      return;
    }

    setError(null);
    const bmi = calculateBmi(heightNumber, weightNumber);
    setResult({ bmi, category: bmiCategory(bmi) });
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>BMI Calculator</Text>

      <Text style={styles.label}>Height (cm)</Text>
      <TextInput
        style={styles.input}
        value={height}
        onChangeText={setHeight}
        keyboardType="decimal-pad"
      />

      <Text style={styles.label}>Weight (kg)</Text>
      <TextInput
        style={styles.input}
        value={weight}
        onChangeText={setWeight}
        keyboardType="decimal-pad"
      />

      <TouchableOpacity style={styles.button} onPress={calculate}>
        <Text style={styles.buttonText}>Calculate BMI</Text>
      </TouchableOpacity>

      {error && <Text style={styles.errorText}>{error}</Text>}

      {result && (
        <View style={[styles.resultBox, { borderColor: result.category.color }]}>
          <Text style={[styles.bmiValue, { color: result.category.color }]}>
            {result.bmi.toFixed(1)}
          </Text>
          <Text style={[styles.categoryText, { color: result.category.color }]}>
            {result.category.label}
          </Text>
        </View>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, paddingTop: 80, paddingHorizontal: 24 },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 24, textAlign: 'center' },
  label: { color: '#6b7280', marginBottom: 4 },
  input: { borderWidth: 1, borderColor: '#d1d5db', borderRadius: 8, padding: 10, marginBottom: 16, fontSize: 16 },
  button: { backgroundColor: '#2563eb', padding: 14, borderRadius: 8, alignItems: 'center' },
  buttonText: { color: 'white', fontWeight: 'bold', fontSize: 16 },
  errorText: { color: '#dc2626', marginTop: 12, textAlign: 'center' },
  resultBox: { marginTop: 24, borderWidth: 2, borderRadius: 12, padding: 24, alignItems: 'center' },
  bmiValue: { fontSize: 36, fontWeight: 'bold' },
  categoryText: { fontSize: 16, marginTop: 4 },
});

4. Explanation

  • height.replace(',', '.') – accounts for users who often type a comma instead of a period as the decimal separator; without this normalization, parseFloat('1,75') would only return 1.
  • keyboardType="decimal-pad" shows a numeric keyboard WITH a decimal point – more user-friendly than the default keyboard for purely numeric input fields.
  • The validation (!heightNumber || heightNumber <= 0) checks SIMULTANEOUSLY for NaN (on invalid input like "abc", parseFloat returns NaN, which is falsy) AND for nonsensical negative/zero values in a single expression.
  • bmiCategory() is deliberately extracted as a PURE function (no component state, no side effects) – easily testable in isolation and reusable, should the app later be extended with a history view.

5. Outputs

Ausgabe
Title "BMI Calculator", two labeled input fields (pre-filled "175"/"70"), a blue "Calculate BMI" button. After tapping, a bordered result box appears with a large number "22.9" and text "Normal weight", both colored green (the color switches to blue/orange/red depending on the BMI range). On invalid input (e.g. an empty field), red text "Please enter valid, positive numbers." appears instead.