¿Cómo puedo obtener el número de líneas de un texto antes de que se represente?
He implementado mi propio "Texto plegable" (el texto típico de leer más/menos), pero estoy experimentando un error al calcular el número de líneas con el apoyo "onLayout".
Solo quiero renderizar una versión corta del texto original con un "botón leer más"... pero, para trabajar con el apoyo "onLayout", el texto completo tiene que renderizarse antes de ocultarlo.
Mi código actual funciona... pero necesito evitar mostrar el texto completo antes del cálculo del total de líneas... ¿es posible?
Echa un vistazo a este snack , para notar el fallo (prueba en dispositivos iOS o Android, no en web).
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> ); }¿Qué tal si... simplemente inicializas el estado isCollapsed con true ?
const [isCollapsed, setIsCollapsed] = useState(true);