ReactJS convert HTML string to JSX

JavascriptJqueryAjaxReactjs

Javascript Problem Overview


I'm having trouble dealing with facebook's ReactJS. Whenever I do ajax and want to display an html data, ReactJS displays it as text. (See figure below)

ReactJS render string

The data is displayed through the success callback function of the jquery Ajax.

$.ajax({
   url: url here,
   dataType: "json",
   success: function(data) {
      this.setState({
           action: data.action
      })
   }.bind(this)
});

enter image description here

Is there any easy way to convert this into html? How should I do it using ReactJS?

Javascript Solutions


Solution 1 - Javascript

By default, React escapes the HTML to prevent XSS (Cross-site scripting). If you really want to render HTML, you can use the dangerouslySetInnerHTML property:

<td dangerouslySetInnerHTML={{__html: this.state.actions}} />

React forces this intentionally-cumbersome syntax so that you don't accidentally render text as HTML and introduce XSS bugs.

Solution 2 - Javascript

There are now safer methods to accomplish this. The docs have been updated with these methods.

Other Methods

  1. Easiest - Use Unicode, save the file as UTF-8 and set the charset to UTF-8.

    <div>{'First · Second'}</div>

  2. Safer - Use the Unicode number for the entity inside a Javascript string.

    <div>{'First \u00b7 Second'}</div>

or

`<div>{'First ' + String.fromCharCode(183) + ' Second'}</div>`

3. Or a mixed array with strings and JSX elements.

`<div>{['First ', <span>&middot;</span>, ' Second']}</div>`

4. Last Resort - Insert raw HTML using dangerouslySetInnerHTML.

`<div dangerouslySetInnerHTML={{__html: 'First &middot; Second'}} />`

Solution 3 - Javascript

I recommend using Interweave created by milesj. Its a phenomenal library that makes use of a number if ingenious techniques to parse and safely insert HTML into the DOM.

> Interweave is a react library to safely render HTML, filter > attributes, autowrap text with matchers, render emoji characters, and > much more.

  • Interweave is a robust React library that can:
  • Safely render HTML without using dangerouslySetInnerHTML.
  • Safely strip HTML tags.
  • Automatic XSS and injection protection.
  • Clean HTML attributes using filters.
  • Interpolate components using matchers.
  • Autolink URLs, IPs, emails, and hashtags.
  • Render Emoji and emoticon characters.
  • And much more!

Usage Example:

import React from 'react';
import { Markup } from 'interweave';

const articleContent = "<p><b>Lorem ipsum dolor laboriosam.</b> </p><p>Facere debitis impedit doloremque eveniet eligendi reiciendis <u>ratione obcaecati repellendus</u> culpa? Blanditiis enim cum tenetur non rem, atque, earum quis, reprehenderit accusantium iure quas beatae.</p><p>Lorem ipsum dolor sit amet <a href='#testLink'>this is a link, click me</a> Sunt ducimus corrupti? Eveniet velit numquam deleniti, delectus  <ol><li>reiciendis ratione obcaecati</li><li>repellendus culpa? Blanditiis enim</li><li>cum tenetur non rem, atque, earum quis,</li></ol>reprehenderit accusantium iure quas beatae.</p>"

<Markup content={articleContent} /> // this will take the articleContent string and convert it to HTML markup. See: https://milesj.gitbook.io/interweave
//to install package using npm, execute the command
npm install interweave

Solution 4 - Javascript

npm i html-react-parser;

import Parser from 'html-react-parser';

<td>{Parser(this.state.archyves)}</td>

Solution 5 - Javascript

For those still experimenting, npm install react-html-parser

When I installed it it had 123628 weekly downloads.

import ReactHtmlParser from 'react-html-parser'

<div>{ReactHtmlParser(htmlString)}</div>

Solution 6 - Javascript

You can use the following if you want to render raw html in React

<div dangerouslySetInnerHTML={{__html: `html-raw-goes-here`}} />

Example - Render

Test is a good day

Solution 7 - Javascript

This could have been solved by using the content put inside this block {[]} like this. Example could be referred below for better clarity.

{[
   'abc',
   <b>my bold</b>, 
   'some other text'
]} 

This would preserve the formatting for text under tags while the others would be printed as plain text.

Solution 8 - Javascript

i found this js fiddle. this works like this

function unescapeHTML(html) {
    var escapeEl = document.createElement('textarea');
    escapeEl.innerHTML = html;
    return escapeEl.textContent;
}

<textarea className="form-control redactor"
                          rows="5" cols="9"
                          defaultValue={unescapeHTML(this.props.destination.description)}
                          name='description'></textarea>

jsfiddle link

Solution 9 - Javascript

i start using npm package called react-html-parser

Solution 10 - Javascript

You can also use Parser() from html-react-parser. I have used the same. Link shared.

Solution 11 - Javascript

One option that's missing in the existing answers is using <React.Fragment> (available in React v16 and later). I find this best because this allows you to store any html element as a JSX variable and refer to it later. Also because using dangerouslySetInnerHTML is not secure.

For Example

const App = () => {
    const Windows = <React.Fragment>Microsoft <abbr title="Operating System">OS</abbr></React.Fragment>

    return (
      <ul>
        <li>{Windows}</li>
      </ul>
    );
};

ReactDOM.render(<App />, document.getElementById("root"));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Other alternatives and considerations:

  1. If you're fetching the HTML from external sources, then you cannot use this approach because the fetched HTML will be in a string format. In that case you need to parse the HTML using a HTML Parser like html-react-parser
  2. If you don't have any keys or attributes, you can also use <></> which is a shorthand for <React.Fragment></React.Fragment>
  3. Keep in mind that dangerouslySetInnerHTML is dangerous to use because malicious client side code can be injected via script tags:
  4. @Brett has also suggested other alternatives:
  5. Note: using quotes in a JSX Variale
    • You should not surround a JSX variable with quotes (like a regular variable) - you should surround it with <React.Fragment> </ React.Fragment>
    • you should not escape quotes in a html tag of a JSX variable - for example the title in <abbr /> tag above has quotes which are not escaped.

Solution 12 - Javascript

If you know ahead what tags are in the string you want to render; this could be for example if only certain tags are allowed in the moment of the creation of the string; a possible way to address this is use the Trans utility:

import { Trans } from 'react-i18next'
import React, { FunctionComponent } from "react";

export type MyComponentProps = {
    htmlString: string
}

export const MyComponent: FunctionComponent<MyComponentProps> = ({
  htmlString
}) => {
  return (
    <div>
      <Trans
        components={{
          b: <b />,
          p: <p />
        }}
      >
        {htmlString}
      </Trans>
    </div>
  )
}

then you can use it as always

<MyComponent
    htmlString={'<p>Hello <b>World</b></p>'}
/>

Solution 13 - Javascript

This is very simple.
And it works perfectly.

import {settings} from '../settings';


const NavBar = (props) => {
    
    let isLoggedIn=props.isLoggedIn;

    let login_partial = "";
    if(isLoggedIn)
    {login_partial= <li>Log Out</li>;}
    else{
    login_partial=
  <div>
      <li>Login</li>
    <li>Sign Up</li>
</div>;
   }

    return(
        <div>
               <ul>
                    <li>Home</li>
                    <li>Products</li>
                    {login_partial}
                </ul>
        </div>
    )
}
export default NavBar;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPeter WateberView Question on Stackoverflow
Solution 1 - JavascriptSophie AlpertView Answer on Stackoverflow
Solution 2 - JavascriptBrett DeWoodyView Answer on Stackoverflow
Solution 3 - JavascriptArman NischView Answer on Stackoverflow
Solution 4 - JavascriptDonatas KuskysView Answer on Stackoverflow
Solution 5 - Javascriptuser12993865View Answer on Stackoverflow
Solution 6 - JavascriptPanayiotis GeorgiouView Answer on Stackoverflow
Solution 7 - JavascriptSunil KumarView Answer on Stackoverflow
Solution 8 - JavascriptHassan GilakView Answer on Stackoverflow
Solution 9 - JavascriptDayanView Answer on Stackoverflow
Solution 10 - JavascriptAbhra DeyView Answer on Stackoverflow
Solution 11 - JavascriptGangulaView Answer on Stackoverflow
Solution 12 - JavascriptAlejandroView Answer on Stackoverflow
Solution 13 - JavascriptOmar MagdyView Answer on Stackoverflow