'How to pass a variable with text and a link into a React element

If I have a React component like this:

return (
  <p>{obj.text}</p>
)

Where I am passing in a hardcoded value like this:

obj = {
  text: 'This is an example string. I would like a [link here].'
}

Is my only recourse to use dangerouslySetInnerHtml and pass in HTML?

Although this might not be harmful in this particular case, I could see the possibility over time where a developer introduces a variable into obj.text and suddenly a user would be able to enter malicious code.

Is there a neater solution?



Solution 1:[1]

Well if you're wanting to set something as HTML then dangerouslySetInnerHtml is the way to so it. If the HTML you're using isn't something you have complete control over and is something like a user input, then you should always be parsing it anyway to make sure it isn't malicious.

If you want to create a hyperlink then another possibility is to have a function which builds the element and returns that. So for example:

obj = {
  text: 'This is an example string.',
  link: 'www.TastyPotatoes.com'
}

And your render function could be something like this:

buildLink() {
   return(
      <p>
        {obj.text}. <a href={obj.link}>This is a link</a>
      </p>
    );
}

render() {
   return (this.buildLink());
}

That way you're not using dangerouslySetInnerHtml. In the end if you HAVE to set something as HTML directly, always parse it first to make sure it's safe.

Solution 2:[2]

If you want to create a component especially for this use case then what @Jayce444 suggested is the right way to go.

But if you want a more a general approach then you can opt for library like React Linkyfy (https://github.com/tasti/react-linkify/).

I have used it in one of my projects and it just worked great for me.

Here is the simpler form of the component which I am using.

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>);
    }
}

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 Jayce444
Solution 2 Sushil Kumar