0
0
React Nativemobile~20 mins

Form validation patterns in React Native - Mini App: Build & Ship

Choose your learning style9 modes available
Build: User Registration
A simple user registration form that validates input fields before submission.
Target UI
-------------------------
| User Registration     |
|-----------------------|
| Name: [___________]   |
| Email: [___________]  |
| Password: [_______]   |
|                       |
| [ Register ]          |
-------------------------
Three input fields: Name, Email, Password
Name must not be empty
Email must be a valid email format
Password must be at least 6 characters
Show error messages below each field if invalid
Disable Register button if any field is invalid
Show alert 'Registration Successful' on valid submission
Starter Code
React Native
import React, { useState } from 'react';
import { View, Text, TextInput, Button, Alert, StyleSheet } from 'react-native';

export default function UserRegistration() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  // TODO: Add validation state and functions here

  return (
    <View style={styles.container}>
      <Text style={styles.title}>User Registration</Text>
      <Text>Name:</Text>
      <TextInput
        style={styles.input}
        value={name}
        onChangeText={setName}
        placeholder="Enter your name"
        autoCapitalize="words"
        accessibilityLabel="Name input"
      />
      {/* TODO: Show name error message here */}

      <Text>Email:</Text>
      <TextInput
        style={styles.input}
        value={email}
        onChangeText={setEmail}
        placeholder="Enter your email"
        keyboardType="email-address"
        autoCapitalize="none"
        accessibilityLabel="Email input"
      />
      {/* TODO: Show email error message here */}

      <Text>Password:</Text>
      <TextInput
        style={styles.input}
        value={password}
        onChangeText={setPassword}
        placeholder="Enter your password"
        secureTextEntry
        accessibilityLabel="Password input"
      />
      {/* TODO: Show password error message here */}

      <Button
        title="Register"
        onPress={() => { /* TODO: Handle submit */ }}
        disabled={true} // TODO: Enable when form is valid
        accessibilityLabel="Register button"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
    flex: 1,
    justifyContent: 'center',
  },
  title: {
    fontSize: 24,
    marginBottom: 20,
    fontWeight: 'bold',
  },
  input: {
    borderWidth: 1,
    borderColor: '#999',
    borderRadius: 4,
    padding: 8,
    marginBottom: 5,
  },
  errorText: {
    color: 'red',
    marginBottom: 10,
  },
});
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
React Native
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button, Alert, StyleSheet } from 'react-native';

export default function UserRegistration() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const [nameError, setNameError] = useState('');
  const [emailError, setEmailError] = useState('');
  const [passwordError, setPasswordError] = useState('');

  const [isFormValid, setIsFormValid] = useState(false);

  function validateName(value) {
    if (value.trim().length === 0) {
      setNameError('Name cannot be empty');
      return false;
    } else {
      setNameError('');
      return true;
    }
  }

  function validateEmail(value) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(value)) {
      setEmailError('Enter a valid email');
      return false;
    } else {
      setEmailError('');
      return true;
    }
  }

  function validatePassword(value) {
    if (value.length < 6) {
      setPasswordError('Password must be at least 6 characters');
      return false;
    } else {
      setPasswordError('');
      return true;
    }
  }

  useEffect(() => {
    const nameValid = validateName(name);
    const emailValid = validateEmail(email);
    const passwordValid = validatePassword(password);
    setIsFormValid(nameValid && emailValid && passwordValid);
  }, [name, email, password]);

  function handleRegister() {
    Alert.alert('Registration Successful');
    setName('');
    setEmail('');
    setPassword('');
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>User Registration</Text>

      <Text>Name:</Text>
      <TextInput
        style={styles.input}
        value={name}
        onChangeText={setName}
        placeholder="Enter your name"
        autoCapitalize="words"
        accessibilityLabel="Name input"
      />
      {nameError ? <Text style={styles.errorText}>{nameError}</Text> : null}

      <Text>Email:</Text>
      <TextInput
        style={styles.input}
        value={email}
        onChangeText={setEmail}
        placeholder="Enter your email"
        keyboardType="email-address"
        autoCapitalize="none"
        accessibilityLabel="Email input"
      />
      {emailError ? <Text style={styles.errorText}>{emailError}</Text> : null}

      <Text>Password:</Text>
      <TextInput
        style={styles.input}
        value={password}
        onChangeText={setPassword}
        placeholder="Enter your password"
        secureTextEntry
        accessibilityLabel="Password input"
      />
      {passwordError ? <Text style={styles.errorText}>{passwordError}</Text> : null}

      <Button
        title="Register"
        onPress={handleRegister}
        disabled={!isFormValid}
        accessibilityLabel="Register button"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
    flex: 1,
    justifyContent: 'center',
  },
  title: {
    fontSize: 24,
    marginBottom: 20,
    fontWeight: 'bold',
  },
  input: {
    borderWidth: 1,
    borderColor: '#999',
    borderRadius: 4,
    padding: 8,
    marginBottom: 5,
  },
  errorText: {
    color: 'red',
    marginBottom: 10,
  },
});

This solution uses React Native functional components with hooks to manage form state and validation.

We keep track of the input values and their error messages separately. Each field has a validation function that sets an error message if invalid or clears it if valid.

The useEffect hook runs validation whenever any input changes, updating a boolean isFormValid state. This boolean controls whether the Register button is enabled.

When the Register button is pressed, an alert shows success, and the form resets.

Error messages appear below each input if the input is invalid, helping the user fix mistakes before submitting.

Final Result
Completed Screen
-------------------------
| User Registration     |
|-----------------------|
| Name: [John Doe   ]   |
|                       |
| Email: [john@example] |
| Enter a valid email    |
| Password: [******]    |
| Password must be at   |
| least 6 characters    |
|                       |
| [ Register ]          |
-------------------------
User types in each field; errors show if invalid
Register button is disabled until all fields are valid
Tapping Register shows alert 'Registration Successful' and clears form
Stretch Goal
Add a toggle button to show or hide the password text
💡 Hint
Use a state variable to switch the TextInput's secureTextEntry prop between true and false