DEV Community

Cover image for Tips Componente Text de React Native
Kevin Gracia Orejuela
Kevin Gracia Orejuela

Posted on • Updated on

Tips Componente Text de React Native

Una de las particularidades de React Native a diferencia de React en la Web es el uso de exclusivo de la etiqueta o componente predeterminado para el tratamiento de textos, pero este en ocasiones genera ciertas particularidades.

Empecemos con el primer ejemplo de antemano avisando también que por defecto el manejo de estilos en cuanto posicionamiento en React Native se usa Flexbox y uso posición natural es columnas en lugar de filas(rows) como en la web

El ejemplo es el siguiente: se tiene un contenedor donde se agrupan distintas propiedades de texto
así luce el código

<View style={styles.avatarTextContainer}>
          <Text fontWeight={'bold'} fontSize={'subheading'}>
            {fullName}
          </Text>

          <Text
            testID="repositoryDescription"
            style={styles.textDescription}
            color="textSecondary"
          >
            {description}
          </Text>

          <View style={styles.languageContainer}>
            <Text color={'textWhite'}>{language}</Text>
          </View>
        </View>
Enter fullscreen mode Exit fullscreen mode

Los estilos

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'white',
    padding: 5,
  },
  avatarContainer: {
    flexDirection: 'row',
  },
  avatarTextContainer: {
    justifyContent: 'space-between',
    marginLeft: 15,
  },
  languageContainer: {
    backgroundColor: theme.colors.primary,
    padding: 4,
    borderRadius: 2,
  },
  textDescription: {
    flexShrink: 1,
  },
  counterContainer: { justifyContent: 'center', alignItems: 'center' },
  footerItemContainer: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    marginTop: 10,
  },
});
Enter fullscreen mode Exit fullscreen mode

Así luce la vista

Image description

El detalle es que el atributo de lenguaje de programación que está de azul debería lucir como un botón y no ocupar toda la fila disponible, aunque se puede ajustar el tamaño del mismo en su sección de estilos llamado "languageContainer" usando width y height otra opción es usar la propiedad "align-self": "flex-start" de modo que ahora lucirá así:

Image description

Ahora observemos otro inconveniente con el texto de la descripción cuando este es muy largo, empiezan a desbordarse de la pantalla, aquí el comportamiento esperando es que pase a la siguiente línea pero luce así:

Image description

Esto lo podemos solucionar desde el contenedor principal del texto "avatarTextContainer" usando la propiedad de estilo "flexShrink": 1 para que el los hijos se logren encoger adecuadamente con lo que hora luce así:

Image description

Código Final

import { Image, StyleSheet, View } from 'react-native';
import React from 'react';
import Text from './Text';
import theme from '../theme';

const RepositoryItem = ({ repository }) => {
  const {
    id,
    fullName,
    description,
    language,
    forksCount,
    stargazersCount,
    ratingAverage,
    reviewCount,
    ownerAvatarUrl,
    url,
  } = repository;

  const counterKsuffix = (amount) => {
    return amount >= 1000
      ? `${Math.round(amount / 100) / 10}k`
      : String(amount);
  };
  return (
    <View style={styles.container}>
      <View style={styles.avatarContainer}>
        <Image style={styles.avatarImg} source={{ uri: ownerAvatarUrl }} />
        <View style={styles.avatarTextContainer}>
          <Text fontWeight={'bold'} fontSize={'subheading'}>
            {fullName}
          </Text>

          <Text
            testID="repositoryDescription"
            style={styles.textDescription}
            color="textSecondary"
          >
            {description}
          </Text>

          <View style={styles.languageContainer}>
            <Text color={'textWhite'}>{language}</Text>
          </View>
        </View>
      </View>
      <View style={styles.footerItemContainer}>
        <View style={styles.counterContainer}>
          <Text fontWeight={'bold'}>{counterKsuffix(forksCount)}</Text>
          <Text>Forks</Text>
        </View>
        <View style={styles.counterContainer}>
          <Text fontWeight={'bold'}>{counterKsuffix(stargazersCount)}</Text>
          <Text>Stars</Text>
        </View>
        <View style={styles.counterContainer}>
          <Text fontWeight={'bold'}>{counterKsuffix(ratingAverage)}</Text>
          <Text>Rating</Text>
        </View>
        <View style={styles.counterContainer}>
          <Text fontWeight={'bold'}>{counterKsuffix(reviewCount)}</Text>
          <Text>Reviews</Text>
        </View>
      </View>
    </View>
  );
};

export default RepositoryItem;

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'white',
    padding: 5,
  },
  avatarContainer: {
    flexDirection: 'row',
  },
  avatarImg: { height: 80, width: 80, borderRadius: 7 },
  avatarTextContainer: {
    justifyContent: 'space-between',
    flexShrink: 1,
    marginLeft: 15,
  },
  languageContainer: {
    alignSelf: 'flex-start',
    backgroundColor: theme.colors.primary,
    padding: 4,
    borderRadius: 2,
  },
  textDescription: {
    flexShrink: 1,
  },
  counterContainer: { justifyContent: 'center', alignItems: 'center' },
  footerItemContainer: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    marginTop: 10,
  },
});
Enter fullscreen mode Exit fullscreen mode

Top comments (0)