Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

359
Views
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 answers
Answer question

0

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

const [isCollapsed, setIsCollapsed] = useState(true);
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!