Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

358
Visualizações
React Native - Get number of lines of a text (before it is rendered)

Question

How can I get the number of lines of a text before it is rendered?

I have implemented my own "CollapsibleText" (the typical read more/less text), but I am experiencing a bug because of calculating the number of lines with the "onLayout" prop.

I just want to render a short version of the original text with a "read more button"... but, to work with the "onLayout" prop, the full text has to be rendered before hidden it.

My current code works... but I need to avoid rendering the full text before the total lines calculation... is it possible?

Take a look at this snack, to notice the bug (test on iOS or Android devices, not in web).

Code

export default function CollapsibleText({
  children = "",
  numberOfLines = 3,
  ellipsizeMode = "tail",
  containerStyle,
  textStyle = styles.text,
  readMoreButtonStyle = styles.readMoreButton,
  readMoreTextStyle = styles.readMoreText,
}) {
  const { colors } = useTheme();

  const isMounted = useIsMounted();

  const { t } = useLanguage();

  const measured = useRef(false);

  const [isCollapsed, setIsCollapsed] = useState(false);
  const [showReadMoreButton, setShowReadMoreButton] = useState(false);

  const toggleIsCollapsed = () => {
    setIsCollapsed((prevIsCollapsed) => !prevIsCollapsed);
  };

  const handleOnTextLayout = useCallback(
    ({ nativeEvent: { lines } }) => {
      if (isMounted() && !measured.current && lines.length > numberOfLines) {
        measured.current = true;
        setIsCollapsed(true);
        setShowReadMoreButton(true);
      }
    },
    [isMounted]
  );

  const renderReadMoreButton = () => (
    <TouchableOpacity
      activeOpacity={0.75}
      onPress={toggleIsCollapsed}
      style={readMoreButtonStyle}
    >
      <Text style={[{ color: colors.silverChalice }, readMoreTextStyle]}>
        {t(`collapsibleText.${isCollapsed ? "readMore" : "readLess"}`)}
      </Text>
    </TouchableOpacity>
  );

  return (
    <View style={containerStyle}>
      <Text
        numberOfLines={isCollapsed ? numberOfLines : undefined}
        ellipsizeMode={ellipsizeMode}
        onTextLayout={handleOnTextLayout}
        style={textStyle}
      >
        {children}
      </Text>

      {showReadMoreButton && renderReadMoreButton()}
    </View>
  );
}
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

How about... you just initialize the isCollapsed state with true?

const [isCollapsed, setIsCollapsed] = useState(true);
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda