25. Uso de props específicas de cada componente.

 

Tutorial: Uso de Props Específicas de Cada Componente en React Native

📋 Introducción

Cada componente en React Native tiene propiedades (props) específicas que permiten personalizar su comportamiento y apariencia. En este tutorial exploraremos las props más importantes de Text, Image y TextInput, y cómo utilizarlas para mejorar nuestros componentes.


🎯 Objetivo

Mejorar nuestra pantalla de perfil utilizando props específicas para:

  1. Personalizar el TextInput (línea inferior, placeholder, teclado)

  2. Mejorar el estilo del Text (espaciado, truncado, eventos)

  3. Optimizar la Image (redondeo, contenedor)

  4. Aprender a descubrir props disponibles


🛠️ Paso 1: Mejorando el TextInput

Props para mostrar la línea inferior en Android:

tsx

import React, { useState } from 'react';

import { View, Text, TextInput, StyleSheet } from 'react-native';


export const Profile = () => {

  const [name, setName] = useState('');


  return (

    <View style={styles.container}>

      {/* Contenedor para placeholder personalizado */}

      <View style={styles.inputContainer}>

        <Text style={styles.placeholder}>NOMBRE *</Text>

        <TextInput

          style={styles.textInput}

          value={name}

          onChangeText={setName}

          underlineColorAndroid="#000000" // Línea inferior en Android

        />

      </View>

    </View>

  );

};


const styles = StyleSheet.create({

  container: {

    flex: 1,

    padding: 20,

  },

  inputContainer: {

    width: '100%',

    marginTop: 20,

  },

  placeholder: {

    fontSize: 10,

    color: '#099',

    textTransform: 'uppercase',

    fontWeight: 'bold',

    marginBottom: 5,

  },

  textInput: {

    width: '100%',

    height: 40,

  },

});

Más props útiles para TextInput:

tsx

<TextInput

  style={styles.textInput}

  value={name}

  onChangeText={setName}

  // Props básicas

  placeholder="Ingresa tu nombre" // Texto temporal

  placeholderTextColor="#999"     // Color del placeholder

  editable={true}                 // Permite edición

  maxLength={50}                  // Máximo de caracteres

  

  // Props para teclado

  keyboardType="default"          // Tipo de teclado

  autoCapitalize="words"          // Capitalización automática

  autoCorrect={true}              // Corrección automática

  autoComplete="name"             // Autocompletado

  

  // Props específicas de plataforma

  underlineColorAndroid="#000000" // Android: línea inferior

  clearButtonMode="while-editing" // iOS: botón para limpiar

  

  // Props de seguridad

  secureTextEntry={false}         // Para contraseñas

  

  // Eventos

  onFocus={() => console.log('Input enfocado')}

  onBlur={() => console.log('Input perdió foco')}

  onSubmitEditing={() => console.log('Enter presionado')}

/>

Tipos de teclado disponibles:

tsx

keyboardType="default"      // Teclado estándar

keyboardType="numeric"      // Solo números

keyboardType="email-address"// Teclado para email

keyboardType="phone-pad"    // Teclado telefónico

keyboardType="decimal-pad"  // Números y decimales

keyboardType="url"          // Teclado para URLs


✨ Paso 2: Mejorando el Componente Text

Props para control de texto:

tsx

<Text

  style={styles.title}

  numberOfLines={1}           // Limita a 1 línea

  ellipsizeMode="tail"        // Corta al final con "..."

  selectable={true}           // Permite seleccionar texto

  selectionColor="#FF6B6B"    // Color de selección (Android)

  // Eventos

  onPress={() => console.log('Texto presionado')}

  onLongPress={() => console.log('Texto presionado largo')}

  onLayout={(event) => {

    // Obtiene dimensiones después de renderizar

    const { width, height, x, y } = event.nativeEvent.layout;

    console.log(`Ancho: ${width}, Alto: ${height}`);

  }}

>

  PERFIL

</Text>

Estilos mejorados para Text:

tsx

const styles = StyleSheet.create({

  title: {

    fontSize: 28,

    textTransform: 'uppercase',

    fontWeight: '900',        // Grosor de fuente (100-900)

    letterSpacing: 8,         // Espacio entre letras

    marginBottom: 30,         // Margen inferior

  },

  greeting: {

    fontSize: 18,

    fontWeight: 'bold',       // Equivalente a 700

    // FontFamily personalizada (requiere configuración adicional)

  },

});


🖼️ Paso 3: Mejorando el Componente Image

Contenedor para imagen redonda:

tsx

<View style={styles.imageContainer}>

  <Image

    source={{

      uri: 'https://ejemplo.com/imagen.jpg'

    }}

    style={styles.image}

    resizeMode="cover"        // Cómo redimensionar la imagen

    onLoad={() => console.log('Imagen cargada')}

    onError={(error) => console.log('Error:', error.nativeEvent.error)}

  />

</View>

Estilos para imagen circular:

tsx

const styles = StyleSheet.create({

  imageContainer: {

    width: 100,

    height: 100,

    backgroundColor: '#E27683', // Fondo rosa

    borderRadius: 50,           // Hace el contenedor circular

    justifyContent: 'center',   // Centra verticalmente

    alignItems: 'center',       // Centra horizontalmente

    marginVertical: 20,

  },

  image: {

    width: 75,                  // Imagen más pequeña que el contenedor

    height: 75,

    borderRadius: 37.5,         // Hace la imagen circular

  },

});


🔍 Paso 4: Cómo Descubrir Props Disponibles

Método 1: Usando TypeScript (Recomendado)

typescript

// Presiona Ctrl/Cmd + clic en el componente

import { TextInput } from 'react-native';

// Esto te llevará a la definición de tipos

Método 2: Documentación Oficial

Visita: React Native Docs

Método 3: Explorando en el Editor

Al hacer clic derecho → "Go to Definition" en un componente, verás:

typescript

// Ejemplo para TextInput

interface TextInputProps extends TextInputIOSProps, TextInputAndroidProps {

  // Props comunes

  value?: string;

  onChangeText?: (text: string) => void;

  placeholder?: string;

  

  // Y muchas más...

}


📱 Paso 5: Props Específicas por Plataforma

Props solo para iOS:

tsx

<TextInput

  // iOS específico

  clearButtonMode="while-editing" // Botón para limpiar

  clearTextOnFocus={false}        // Limpiar al enfocar

  keyboardAppearance="default"    // Apariencia del teclado

  spellCheck={true}               // Corrección ortográfica

/>

Props solo para Android:

tsx

<TextInput

  // Android específico

  underlineColorAndroid="#000000" // Color de la línea

  numberOfLines={1}               // Número de líneas

  textAlignVertical="center"      // Alineación vertical

/>

Props solo para Text en iOS:

tsx

<Text

  // iOS específico

  adjustsFontSizeToFit={true}     // Ajusta tamaño automáticamente

  minimumFontScale={0.5}          // Escala mínima

  suppressHighlighting={true}     // Elimina efecto al tocar

>

  Texto

</Text>


🎯 Paso 6: Implementación Completa Mejorada

tsx

import React, { useState } from 'react';

import {

  View,

  Text,

  Image,

  TextInput,

  StyleSheet,

  TouchableOpacity,

} from 'react-native';


export const Profile = () => {

  const [name, setName] = useState('');

  const [email, setEmail] = useState('');


  return (

    <View style={styles.mainContainer}>

      {/* Título con props mejoradas */}

      <Text

        style={styles.title}

        numberOfLines={1}

        ellipsizeMode="tail"

        onPress={() => console.log('Título presionado')}

      >

        PERFIL

      </Text>


      {/* Contenedor de imagen circular */}

      <View style={styles.imageContainer}>

        <Image

          source={{

            uri: 'https://www.pngfind.com/pngs/m/610-6104451_image-placeholder-png.png',

          }}

          style={styles.image}

          resizeMode="cover"

          onLoad={() => console.log('Imagen cargada exitosamente')}

        />

      </View>


      {/* Campo de nombre con placeholder personalizado */}

      <View style={styles.inputGroup}>

        <Text style={styles.inputLabel}>NOMBRE *</Text>

        <TextInput

          style={styles.textInput}

          value={name}

          onChangeText={setName}

          placeholder="Ej: Juan Pérez"

          placeholderTextColor="#999"

          underlineColorAndroid="#000000"

          maxLength={50}

          autoCapitalize="words"

          autoCorrect={false}

        />

      </View>


      {/* Campo de email con teclado especializado */}

      <View style={styles.inputGroup}>

        <Text style={styles.inputLabel}>EMAIL *</Text>

        <TextInput

          style={styles.textInput}

          value={email}

          onChangeText={setEmail}

          placeholder="ejemplo@correo.com"

          placeholderTextColor="#999"

          keyboardType="email-address"

          autoCapitalize="none"

          autoComplete="email"

          underlineColorAndroid="#000000"

        />

      </View>


      {/* Botón con feedback */}

      <TouchableOpacity

        style={styles.button}

        onPress={() => console.log('Guardar:', { name, email })}

        activeOpacity={0.7}

      >

        <Text style={styles.buttonText}>GUARDAR CAMBIOS</Text>

      </TouchableOpacity>


      {/* Texto dinámico basado en input */}

      {name ? (

        <Text style={styles.greeting}>

          ¡Hola, {name}!

        </Text>

      ) : null}

    </View>

  );

};


const styles = StyleSheet.create({

  mainContainer: {

    flex: 1,

    backgroundColor: 'white',

    alignItems: 'center',

    paddingHorizontal: 16,

    paddingVertical: 18,

  },

  title: {

    fontSize: 28,

    textTransform: 'uppercase',

    fontWeight: '900',

    letterSpacing: 8,

    marginBottom: 30,

    color: '#333',

  },

  imageContainer: {

    width: 100,

    height: 100,

    backgroundColor: '#E27683',

    borderRadius: 50,

    justifyContent: 'center',

    alignItems: 'center',

    marginBottom: 40,

  },

  image: {

    width: 75,

    height: 75,

    borderRadius: 37.5,

  },

  inputGroup: {

    width: '100%',

    marginBottom: 20,

  },

  inputLabel: {

    fontSize: 10,

    color: '#099',

    textTransform: 'uppercase',

    fontWeight: 'bold',

    marginBottom: 5,

  },

  textInput: {

    width: '100%',

    height: 40,

    borderBottomWidth: 1,

    borderBottomColor: '#000',

    fontSize: 16,

    paddingHorizontal: 0,

  },

  button: {

    backgroundColor: '#007AFF',

    paddingHorizontal: 30,

    paddingVertical: 12,

    borderRadius: 8,

    marginTop: 20,

  },

  buttonText: {

    color: 'white',

    fontSize: 16,

    fontWeight: '600',

    textTransform: 'uppercase',

  },

  greeting: {

    fontSize: 18,

    fontWeight: '600',

    color: '#333',

    marginTop: 20,

  },

});


🔧 Paso 7: Patrones Comunes y Mejores Prácticas

1. Manejo de estado con TextInput:

tsx

// PATRÓN CORRECTO

const [text, setText] = useState('');


<TextInput

  value={text}

  onChangeText={setText} // setText(valor) automáticamente

/>


// EQUIVALENTE EXPLÍCITO

<TextInput

  value={text}

  onChangeText={(newText) => setText(newText)}

/>

2. Validación en tiempo real:

tsx

<TextInput

  value={email}

  onChangeText={(newEmail) => {

    // Validación básica

    if (newEmail.includes('@')) {

      setEmail(newEmail);

    }

  }}

/>

3. Refs para manejo de focus:

tsx

const emailRef = useRef<TextInput>(null);


<TextInput

  ref={emailRef}

  onSubmitEditing={() => {

    // Al presionar "enter", enfoca el siguiente campo

    passwordRef.current?.focus();

  }}

/>


📚 Resumen de Props Importantes

TextInput Props Esenciales:

Prop

Descripción

Ejemplo

value

Valor actual

value={text}

onChangeText

Al cambiar texto

onChangeText={setText}

placeholder

Texto temporal

placeholder="Email"

keyboardType

Tipo de teclado

keyboardType="email-address"

secureTextEntry

Para contraseñas

secureTextEntry={true}

maxLength

Máximo caracteres

maxLength={10}

underlineColorAndroid

Línea en Android

underlineColorAndroid="#000"

Text Props Esenciales:

Prop

Descripción

Ejemplo

numberOfLines

Límite de líneas

numberOfLines={2}

ellipsizeMode

Cómo truncar

ellipsizeMode="tail"

selectable

Seleccionable

selectable={true}

onPress

Evento al tocar

onPress={handlePress}

Image Props Esenciales:

Prop

Descripción

Ejemplo

resizeMode

Redimensionamiento

resizeMode="contain"

onLoad

Al cargar

onLoad={handleLoad}

onError

Al error

onError={handleError}


💡 Consejos Finales

  1. Explora las props: Usa Ctrl/Cmd + clic para ver todas las props disponibles

  2. Documentación: Consulta reactnative.dev para ejemplos

  3. Prueba en ambas plataformas: Algunas props solo funcionan en iOS o Android

  4. TypeScript es tu amigo: El autocompletado te mostrará todas las opciones

  5. Experimenta: La mejor manera de aprender es probando diferentes props


🎓 Lo que Aprendiste

✅ Cómo usar props específicas para personalizar componentes
✅ Diferencias entre props de iOS y Android
✅ Cómo descubrir props disponibles en TypeScript
✅ Patrones comunes para manejo de formularios
✅ Mejoras visuales con estilos avanzados

¡Sigue explorando las props de cada componente para crear interfaces más ricas y funcionales


Comentarios

Entradas más populares de este blog

Guía Paso a Paso para Entender React Native (antes del Tutorial)

Tutorial: Aplicación React Native para Agregar Tareas - Minimalista

5. Vista Rapida: Estructura Projecto Base