fawaz-ahmed / react-native-read-more

React native library to show text in a condensed way and expand when needed. Drop in replacement for Text component and highly customizable. Can be used with expo or native cli for react native.
https://www.npmjs.com/package/@fawazahmed/react-native-read-more
MIT License
274 stars 37 forks source link

CustomTextComponent issues #65

Closed UmarFKhawaja closed 2 years ago

UmarFKhawaja commented 2 years ago

I am trying to render some Markdown formatted text in a ReadMore. For this to work, I have to send the Markdown component to ReadMore in the customTextComponent prop.

When I do the following, it produces an error: undefined is not an object (evaluating 'node.children.map')

This seems to be an error from within the Markdown component.

import { View } from 'react-native';
import Markdown from 'react-native-markdown-display';
import ReadMore from '@fawazahmed/react-native-read-more';
import { TranslatedQuestion } from '../../../../types';
import { styles } from '../../styles';

const NUMBER_OF_LINES = 10;

export function QuestionView({ translation }: { translation: TranslatedQuestion }) {
  return (
    <View style={styles.innerContainer}>
      <ReadMore numberOfLines={NUMBER_OF_LINES} style={styles.text} customTextComponent={Markdown}/>
    </View>
  );
}

The same thing happens if I provide a simple functional component wrapping the Markdown component, as follows:

import { View } from 'react-native';
import Markdown from 'react-native-markdown-display';
import ReadMore from '@fawazahmed/react-native-read-more';
import { TranslatedQuestion } from '../../../../types';
import { styles } from '../../styles';

const NUMBER_OF_LINES = 10;

export function QuestionView({ translation }: { translation: TranslatedQuestion }) {
  return (
    <View style={styles.innerContainer}>
      <ReadMore numberOfLines={NUMBER_OF_LINES} style={styles.text} customTextComponent={CustomTextComponent}>
        {translation?.text}
      </ReadMore>
    </View>
  );
}

function CustomTextComponent( { children }: { children: string }) {
  return (
    <Markdown>
      {children}
    </Markdown>
  );
}

If I wrap the Markdown component with an inline functional component, as follows, it renders, but twice, one after the other.

import { View } from 'react-native';
import Markdown from 'react-native-markdown-display';
import ReadMore from '@fawazahmed/react-native-read-more';
import { TranslatedQuestion } from '../../../../types';
import { styles } from '../../styles';

const NUMBER_OF_LINES = 10;

export function QuestionView({ translation }: { translation: TranslatedQuestion }) {
  return (
    <View style={styles.innerContainer}>
      <ReadMore numberOfLines={NUMBER_OF_LINES} style={styles.text} customTextComponent={() => <Markdown>{translation?.text}</Markdown>}/>
    </View>
  );
}

Any help I can get on this will be much appreciated.

fawaz-ahmed commented 2 years ago

Hi @UmarFKhawaja , thanks for putting this bug here. I will try to reproduce this.

For multiple rendering, this component actually renders the component multiple times (hidden behind) to calculate the text width and lines. Also the see more and see less texts are rendered separately using the custom component.

UmarFKhawaja commented 2 years ago

Thanks @fawaz-ahmed. When I say rendered twice, I mean that it shows up twice on screen, not rendered in the sense that the render loop is run twice.

fawaz-ahmed commented 2 years ago

I see. Can you share a screenshot ?


From: Umar Farooq Khawaja @.> Sent: Friday, May 20, 2022 1:59:51 PM To: fawaz-ahmed/react-native-read-more @.> Cc: Fawaz Ahmed @.>; Mention @.> Subject: Re: [fawaz-ahmed/react-native-read-more] CustomTextComponent issues (Issue #65)

Thanks @fawaz-ahmedhttps://github.com/fawaz-ahmed. When I say rendered twice, I mean that it shows up twice on screen, not rendered in the sense that the render loop is run twice.

— Reply to this email directly, view it on GitHubhttps://github.com/fawaz-ahmed/react-native-read-more/issues/65#issuecomment-1132656053, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEJEVIEZPNXUICPIXXHO5WDVK5IAPANCNFSM5WJ7ZKLQ. You are receiving this because you were mentioned.Message ID: @.***>

UmarFKhawaja commented 2 years ago

Apologies about the delay. Here's a screenshot.

Photo 30-05-2022, 18 16 10

UmarFKhawaja commented 2 years ago

The first two paragraphs in the screenshot above are being rendered via the ReadMore component, starting from "Fusce" and ending at "aliquet".

fawaz-ahmed commented 2 years ago

@UmarFKhawaja I debugged a bit. The problem is the Markdown component is not passing additional props like onLayout or onTextLayout down to the children component. ReadMore component will not work without it, since it needs those callback props to measure the text width and lines.

fawaz-ahmed commented 2 years ago

Since the issue is with Md component not passing down all props to child components, I will de-scope this issue and close this bug. @UmarFKhawaja if you have any update, you may re-open.

PS: You can resolve this issue with forking the original Md github repo and update it to pass down all props down to the lowest Text component: index -> AstRenderer -> rules based components