Joppe Meijers
Joppe Meijers

Reputation: 299

Show html-tags in React Native

I have a JSON file with a lot of text on various topics. Now I would like to display it in the app but the text contains html tag like <i> </i>, <a href="#"> </a>, <b> </b> etc. I would like to be visible in the text but React Native shows these characters as plain text. I tried with string.replace ("<i>", [function]) but that doesn't work either. Is there someone who has a suitable solution for me?

this is my current map function:

{this.state.selectedData.map((item) =>(
                       <Text style={{width:ScreenWidth}}>{item}{"\n"}{"\n"}</Text>
         
                    ))}

I already tried to replace like this:

    const B = (props) => <Text style={{fontWeight: 'bold'}}>{props.children}</Text>
{this.state.selectedData.map((item) =>(
                           <Text style={{width:ScreenWidth}}>{item.replace("<i>",<B>}{"\n"}{"\n"}</Text>
             
                        ))}

But it is not possible to do that. Does someone have experience with this?

Upvotes: 0

Views: 1507

Answers (2)

S.N.B
S.N.B

Reputation: 813

No Problem , You will need to install react-native-render-html plugin, that will render html tags for you ,

https://www.npmjs.com/package/react-native-render-html

import React, { Component } from "react";
import { ScrollView, Dimensions } from "react-native";
import HTML from "react-native-render-html";
import { IGNORED_TAGS, } from 'react-native-render-html/src/HTMLUtils';

const htmlContent = `
    <h1>This HTML snippet is now rendered with native components !</h1>
`;

export default function Demo() {
   const deviceWidth = Dimensions.get("window").width;
// props
    tagsStyles= {
 i: { textAlign: 'center', fontStyle: 'italic', color: 'grey' } 
    }
    classesStyles={
      'last-paragraph': { textAlign: 'right', color: 'teal', fontWeight: '800' }
   }

  return (
    <ScrollView style={{ flex: 1 }}>
      <HTML 
       source={{ html: htmlContent }} 
       contentWidth={deviceWidth } 
         // classesStyles={classStyles}
          tagsStyles={tagsStyles}
            contentWidth={deviceWidth}
            imagesMaxWidth={deviceWidth } 
     />
    </ScrollView>
  );
}

NOTE: the plugin has issues with rendering table tags

you will need to install additional @native-html/table-plugin and react-native-webview plugin and use it together with react-native-render-html

Upvotes: 1

Honey
Honey

Reputation: 2398

Using WebView could be another option for you. https://medium.com/@sumitkumarpradhan96/rendering-raw-html-in-your-react-native-application-6c8463c2b69

{this.state.selectedData.map((item) =>(
 <WebView
  style={{width: ScreenWidth}}
  javaScriptEnabled={true}
  domStorageEnabled={true}
  source={{ html: item}}
 />
))}

Update You can set the webview height dynamically and here is the solution : https://github.com/react-native-webview/react-native-webview/blob/master/docs/Guide.md#communicating-between-js-and-native

Here is the solution: 1. Define script to send document height to native env after loaded website. 2. Handle onMesssage of webview component and reset Height via state.

const webViewScript = `
  setTimeout(function() { 
    window.postMessage(document.documentElement.scrollHeight); 
  }, 500);
  true; // note: this is required, or you'll sometimes get silent failures
`;


...
constructor(props) {
    super(props);
    this.state = {
      webheight:100,
    }

...

<WebView style={{height: this.state.webheight}}
  automaticallyAdjustContentInsets={false}
  scrollEnabled={false}
  source={{uri: "http://<your url>"}}
  onMessage={event => {
    this.setState({webheight: parseInt(event.nativeEvent.data)});
  }}
  javaScriptEnabled={true}
  injectedJavaScript ={webViewScript}
  domStorageEnabled={true}
></WebView>

Upvotes: 0

Related Questions