ReactJS convert HTML string to JSX
JavascriptJqueryAjaxReactjsJavascript 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)
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)
});
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
-
Easiest - Use Unicode, save the file as UTF-8 and set the
charset
to UTF-8.<div>{'First · Second'}</div>
-
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>·</span>, ' Second']}</div>`
4. Last Resort - Insert raw HTML using dangerouslySetInnerHTML
.
`<div dangerouslySetInnerHTML={{__html: 'First · 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:
- 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
- If you don't have any keys or attributes, you can also use
<></>
which is a shorthand for<React.Fragment></React.Fragment>
- Keep in mind that
dangerouslySetInnerHTML
is dangerous to use because malicious client side code can be injected via script tags: - @Brett has also suggested other alternatives:
- 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.
- You should not surround a JSX variable with quotes (like a regular variable) - you should surround it with
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;