React native & structured data

What’s the best way to render structured text in react native (or react native web view)? Do you have any implementation/recommendations?

Hey @rislam have you seen already our React component here: https://github.com/datocms/react-datocms#structured-text

Not sure if anyone has used it in a React native project yet, but it might work :slight_smile: Let me know if you have any problems with that.

No, it doesn’t work. datocms ST generates HTML, which can’t be rendered natively in react native.

Hello @rislam1

You can use WebView to do so: Render HTML in React Native - Stack Overflow

Or if you prefer an out of the box solution you can also use this package: https://www.npmjs.com/package/react-native-render-html

did that initially. we lost control of rendering. However, using customNodeRules with the help of this (structured-text/types.ts at main · datocms/structured-text · GitHub), was able to achieve native rendering.

customNodeRules={[
        renderNodeRule(isRoot, ({ key, children }) => {
          return (
            <View style={styles.body} key={key}>
              {children}
            </View>
          )
        }),
        renderNodeRule(isHeading, ({ node, children, key }) => {
          return (
            <Text key={key} style={styles[`h${node.level}`]}>
              {children}
            </Text>
          )
        }),
        renderNodeRule(isParagraph, ({ key, children }) => {
          if (pluss || minus) {
            return (
              <PlussMinus
                key={key}
                children={children}
                dtype={pluss ? 'pluss' : 'minus'}
              />
            )
          }
          return (
            <Text key={key} style={styles.p}>
              {children}
            </Text>
          )
        }),
        renderNodeRule(isBlockquote, ({ key, node, children, attribution }) => {
          return (
            <View key={key} style={styles.blockquote}>
              <Text style={styles.quote}>{children}</Text>
              <Text style={styles.attribution}>{node.attribution}</Text>
            </View>
          )
        }),
        renderNodeRule(isList, ({ key, children }) => {
          return (
            <View key={key} style={styles.ul}>
              {children}
            </View>
          )
        }),
        renderNodeRule(isListItem, ({ key, children }) => {
          return (
            <View key={key} style={styles.li}>
              <Text style={styles.dot}>{'\u2022'}</Text>
              <Text>{children}</Text>
            </View>
          )
        }),
        renderNodeRule(isLink, ({ node, children, key }) => {
          return (
            <InlineLink
              key={key}
              title={children}
              url={node.url}
              componentId={componentId}
            />
          )
        }),
      ]}
      customMarkRules={[
        renderMarkRule(
          (node) =>
            ['strong', 'emphasis', 'underline', 'strikethrough'].includes(node),
          ({ key, mark, children }) => {
            return (
              <Text key={key} style={styles[mark]}>
                {children}
              </Text>
            )
          },
        ),
      ]}
      renderText={(text, key) => {
        return <Text key={key}>{text}</Text>
      }}
      renderNode={(_node, { key }, children) => {
        return <View key={key}>{children}</View>
      }}
1 Like