Reputation: 13
I'm trying to render a link, which is found in an array of objects with properties and values.
const arr = [
{
id: 1,
title: "This is a title",
body: [
"This is some stuff. Lorem ipsum, lorizzle for shizzle.",
"Click here to send an <Link to="mailto:[email protected]">email</Link>"
]
},
{
id: 2,
title: "This is another title",
body: [
"Moar stuff.",
"Here is ma' <Link to="mailto:[email protected]">email</Link>"
]
}
]
I'm using this logic to map through the array's objects and store them inside an array of components. This works as intended, if all I'm intending to do is just render some text in a paragraph. When it comes to links, simply this won't work. My guess is that React takes the string for text, and renders the entire thing as text. It doesn't care of the contents.
<section key={item.key} className="">
<h2 className="text-base">{item.title}</h2>
{
item.body.map(function(paragraph) {
return(
<p className="text-sm">{paragraph}</p>
)
})
}
</section>
I've tried enclosing the Link tags within curly braces, to concatenate the string and email (as it would appear in the HTML), string template literals. Nothing worked.
I'm not sure there is a dependency I'm missing or a step. Perhaps the approach I'm taking is wrong? Maybe what I'm trying to do is impossible in React?
Would appreciate some light shed on this matter.
Upvotes: 1
Views: 2584
Reputation: 9105
Some corrections in your question what i found
Assuming you wanted to have a anchor tag
so tweaking your array , Changes
<a href='mailto:[email protected]'>email</a>
instead of <Link to="mailto:[email protected]">email</Link>
"Click here to send an <Link to="mailto:[email protected]">email</Link>"
instead "Click here to send an <a href='mailto:[email protected]'>email</a>"
, quotes should be used properly inside double quotes you need to have single quotes or vice versaDoing the above changes adding the solution
Here you can have multiple approaches
Example
html-react-parser
Code Snippet
App.js
import React, { Fragment } from "react";
import Parser from "html-react-parser";
const arr = [
{
id: 1,
title: "This is a title",
body: [
"This is some stuff. Lorem ipsum, lorizzle for shizzle.",
"Click here to send an <a href='mailto:[email protected]'>email</a>"
]
},
{
id: 2,
title: "This is another title",
body: [
"Moar stuff.",
"Here is ma' <a href='mailto:[email protected]'>email</a>"
]
}
];
export default function App() {
return (
<Fragment>
{arr.map(item => (
<section key={item.key} className="">
<h2 className="text-base">{item.title}</h2>
{item.body.map(function(paragraph) {
return <p className="text-sm">{Parser(paragraph)}</p>;
})}
</section>
))}
</Fragment>
);
}
dangerouslySetInnerHTML is React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it’s easy to inadvertently expose your users to a cross-site scripting (XSS) attack.
Code snippet
App.js
import React, { Fragment } from "react";
const arr = [
{
id: 1,
title: "This is a title",
body: [
"This is some stuff. Lorem ipsum, lorizzle for shizzle.",
"Click here to send an <a href='mailto:[email protected]'>email</a>"
]
},
{
id: 2,
title: "This is another title",
body: [
"Moar stuff.",
"Here is ma' <a href='mailto:[email protected]'>email</a>"
]
}
];
export default function App() {
return (
<Fragment>
{arr.map(item => (
<section key={item.key} className="">
<h2 className="text-base">{item.title}</h2>
{item.body.map(function(paragraph) {
return (
<p
className="text-sm"
dangerouslySetInnerHTML={{ __html: paragraph }}
/>
);
})}
</section>
))}
</Fragment>
);
}
In the above approach, you can do a dompurify and set with dangerouslysetinnerhtml to avoid the XSS attacks
import DOMPurify from "dompurify";
<p
className="text-sm"
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(paragraph) }}
/>;
I hope this will give a better understanding 😊
Upvotes: 1
Reputation: 4623
This would be a very naive approach to transfering jsx within array.
const arr = [
{
id: 1,
title: "This is a title",
body: [
["This is some stuff. Lorem ipsum, lorizzle for shizzle."],
["Click here to send an ", <Link to="mailto:[email protected]">email</Link>"]
]
},
item.body.map(function(paragraph) {
const content = paragraph.reduce((combined, elem) => {
return content + elem;
});
return(
<p className="text-sm">{paragraph}</p>
)
});
Upvotes: 1
Reputation: 3244
you might try using dangerouslySetInnerHtml
.
Something like this: <div dangerouslySetInnerHtml={paragraph} />
This attribute is named like that with a reason, so be careful about what you send in there, as it might lead to XSS injections.
Learn more about it here: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
Upvotes: 0