'how can you render an HTML array?
I have an array with <p> and <div> items and I'm trying to render them as HTML, but whenever I try to render it, the values just appear as plain code and not the normal paragraphs. So I have an array with let's say that this information:
<p>The first paragraph of this pinned topic will be visible as a welcome message to all new visitors on your homepage. It’s important!</p>
<p><strong>Edit this</strong> into a brief description of your community:</p>
And when it gets rendered in the page, it gets rendered as this instead of the paragraph that should be rendered it gets rendered as plain code:
This is the code I've used for render:
useEffect(() => {
axios.get(`/api/get-post?id=${pid}`)
.then(res => setPostData(res.data))
.catch(err => console.log(err.response))
}, [])
console.log(postData?.post_stream?.posts[0]?.cooked)
return (
<div>
<div className={styles.containerPadding}>
<div className={styles.mainContainer}>
<div className={styles.blackLine}>
</div>
<div className={styles.titleContainer}>
<div>
<h1>{postData.title}</h1>
</div>
<div>
<h1></h1>
</div>
</div>
<div className={styles.postInformationContainer}>
<div>
</div>
<div>
<p>{postData?.post_stream?.posts[0]?.cooked}</p>
</div>
</div>
</div>
</div>
</div>
Solution 1:[1]
You can use dangerouslySetInnerHTML for converting your string data to HTML, but for safety (avoiding XSS attack), you should sanitize your HTML string before using dangerouslySetInnerHTML by DOMPurify
import DOMPurify from 'dompurify'
const sanitizedHtml = DOMPurify.sanitize(postData?.post_stream?.posts[0]?.cooked)
And then call it like this
dangerouslySetInnerHTML={{__html: sanitizedHtml}}
useEffect(() => {
axios.get(`/api/get-post?id=${pid}`)
.then(res => setPostData(res.data))
.catch(err => console.log(err.response))
}, [])
const sanitizedHtml = DOMPurify.sanitize(postData?.post_stream?.posts[0]?.cooked)
return (
<div>
<div className={styles.containerPadding}>
<div className={styles.mainContainer}>
<div className={styles.blackLine}>
</div>
<div className={styles.titleContainer}>
<div>
<h1>{postData.title}</h1>
</div>
<div>
<h1></h1>
</div>
</div>
<div className={styles.postInformationContainer}>
<div>
</div>
<div>
<p dangerouslySetInnerHTML={{__html: sanitizedHtml}}></p>
</div>
</div>
</div>
</div>
</div>
One side note, without HTML string sanitization, your HTML data can be interfered by some script injections which would harm your website or your system.
Solution 2:[2]
You can use html-react-parser package
This is how your code will look like
import parse from 'html-react-parser'
useEffect(() => {
axios.get(`/api/get-post?id=${pid}`)
.then(res => setPostData(res.data))
.catch(err => console.log(err.response))
}, [])
return (
<div>
<div className={styles.containerPadding}>
<div className={styles.mainContainer}>
<div className={styles.blackLine}>
</div>
<div className={styles.titleContainer}>
<div>
<h1>{postData.title}</h1>
</div>
<div>
<h1></h1>
</div>
</div>
<div className={styles.postInformationContainer}>
<div>
</div>
<div>
<p>{parse(postData?.post_stream?.posts[0]?.cooked)}</p>
</div>
</div>
</div>
</div>
</div>
Solution 3:[3]
You can use 'dangerouslySetInnerHTML' like everyone else.
And I need to register the tags to use.
import DOMPurify from 'dompurify';
<div
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(
view_inner ?? '<div>Unable to get data.</div>',
{
FORCE_BODY: true,
ADD_TAGS: ['style'],
ADD_ATTR: ['target'],
ALLOWED_TAGS: [
'span',
'div',
'link',
'table',
'thead',
'tr',
'th',
'tbody',
'td',
],
},
),
}}
/>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Monis Khan |
| Solution 3 | xersuy |
