Currently I have this in one of my ponents:
{someObject.map(obj => (
<div
dangerouslySetInnerHTML={{
__html: obj.text
}}
/>
))}
Basically, I am mapping over someObject
which on another file. The structure is like this:
export default someObject = [
{
obj: "<p>Some text 1.</p>"
},
{
obj: "<p>Some text 2.</p>"
}
]
I'm just simplifying the content for demonstration's sake. However, I ran into a problem because I need to use the <Link />
ponent in one of the items. As in:
export default someObject = [
{
obj: "<p>Some text 1.</p>"
},
{
obj: "<p>Some text 2.</p>"
},
{
obj: "<p>Some text 2 and <Link to="/someroute">link</Link>.</p>"
}
]
However, it's not working because that entire <p></p>
tag is wrapped in dangerouslySetInnerHTML
.
I can just use plain <a></a>
tag for the link but that doesn't seem like a good solution as the entire application would reload instead of just going to another route.
What are the other options to make this work?
Currently I have this in one of my ponents:
{someObject.map(obj => (
<div
dangerouslySetInnerHTML={{
__html: obj.text
}}
/>
))}
Basically, I am mapping over someObject
which on another file. The structure is like this:
export default someObject = [
{
obj: "<p>Some text 1.</p>"
},
{
obj: "<p>Some text 2.</p>"
}
]
I'm just simplifying the content for demonstration's sake. However, I ran into a problem because I need to use the <Link />
ponent in one of the items. As in:
export default someObject = [
{
obj: "<p>Some text 1.</p>"
},
{
obj: "<p>Some text 2.</p>"
},
{
obj: "<p>Some text 2 and <Link to="/someroute">link</Link>.</p>"
}
]
However, it's not working because that entire <p></p>
tag is wrapped in dangerouslySetInnerHTML
.
I can just use plain <a></a>
tag for the link but that doesn't seem like a good solution as the entire application would reload instead of just going to another route.
What are the other options to make this work?
Share Improve this question asked Jan 25, 2019 at 3:09 catandmousecatandmouse 11.8k24 gold badges95 silver badges158 bronze badges 3- 3 why not just convert them to simple JSX snippets and use them like regular react ponent children? – Derek Commented Jan 25, 2019 at 3:19
- @Derek Can elaborate on that? Like an example? – catandmouse Commented Jan 25, 2019 at 3:59
- 1 @Derek Never mind, I got what you mean. Realised I can actually use JSX as value of the object. – catandmouse Commented Jan 25, 2019 at 4:10
3 Answers
Reset to default 2Why don't you just export the object as a jsx object? I think use dangerouslySetInnerHTML
is a bad practice, it might cause XSS attack.
const someObject = [
{
obj: <p>Some text 1.</p>
},
{
obj: <p>Some text 2.<a href="https://google.">google</a></p>
}
]
class App extends React.Component {
render(){
return (
<div className="App">
<h1>Hello world</h1>
<h2>Jsx object goes here {someObject[1].obj}</h2>
</div>
)};
}
const rootElement = document.getElementById("container");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your ponent. -->
</div>
-
There's is two ways to solve this problem :
First Way :
it's like a more general approach you can use it to opt your code. try to use this library (https://github./tasti/react-linkify/)
Here's the simpler form of the ponent :
import React, {PropTypes} from 'react';
import Linkify from 'react-linkify';
export default class TextWithLink extends React.Component {
constructor(props) {
super(props);
}
render() {
let text = this.props.text;
if(this.props.showLink) {
text = <Linkify properties={{target: '_blank', rel: "nofollow noopener"}}>{text}</Linkify>
}
return (<div>{text}</div>);
}
}
Second Way :
In case, if you want to create a hyperlink (<a>
), you should have a function which builds elements and returns the result.
Example :
list = {
text: 'hello world',
link: 'www.facebook.'
}
And the render function could be something like :
buildLink() {
return(
<p>
{list.text}. <a href={list.link}>{list.link}</a>
</p>
);
}
render() {
return (this.buildLink());
}
export default someObject = [
{
obj: "<p>Some text 1.</p>"
},
{
obj: "<p>Some text 2.</p>"
},
{
obj: linkto('/someroute')
}
]
linkto will solve your issue.