简体   繁体   中英

How to use <Link /> component inside dangerouslySetInnerHTML

Currently I have this in one of my components:

{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 /> component 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?

Why 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.com">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.com/ajax/libs/react/15.6.2/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script> <div id="container"> <!-- This element's contents will be replaced with your component. --> </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.com/tasti/react-linkify/ )

Here's the simpler form of the component :

 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.com' } 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM