2

This is how I'm trying to replace some strings with elements inside the render()-method of my component. But this fails, as I'm getting the replaced string as a real string instead of an elements.

What do I have to do, to get Link as a rendered Link-element? Right now it is just a string output.

And is this the correct 'react'-way to do that?

return (
  <List>
    {
      elements.map(e => {
        return (
          <List.Item>
            {
              links ? links.map(link => {
                return e.content.replace(
                  new RegExp(link.label, 'gi'),
                    '<Link to="/' + link.id + '">$&</Link> (<Icon name="external" />)'
                )
              }) : ''
            }
          </List.Item>
        )
      })
    }
  </List>
)

elements

[{
    "_id" : "zQS6pXicvXk7K2rZ4",
    "content" : "This is a sample text to add some links",
    "links" : [
        {
            "id" : "Dn59y87PGhkJXpaiZ",
            "type" : "articles",
            "label" : "Sample"
        },
        {
            "id" : "GhkJXpaiZDn59y87P",
            "type" : "articles",
            "label" : "add"
        },
        {
            "id" : "XpaiZDn5GhkJ9y87P",
            "type" : "articles",
            "label" : "External"
        }
    ]
}]
4
  • What does elements typically look like? And links? Commented Jun 23, 2017 at 9:15
  • Both are object arrays. Commented Jun 23, 2017 at 9:33
  • I get that from your code, but it would help seeing example data. Commented Jun 23, 2017 at 9:37
  • I see. You need to split content into an array of strings, like ["This is a", "sample", "text to", "add", "some links"] according to the labels, then replace the array elements with <Link />s. Commented Jun 23, 2017 at 10:47

1 Answer 1

2

Try this:

First replace the string by the Link then render the string by using dangerouslySetInnerHTML, it should work.

Check this example:

let data = [{
    "_id" : "zQS6pXicvXk7K2rZ4",
    "content" : "This is a sample text to add some links",
    "links" : [
        {
            "id" : "Dn59y87PGhkJXpaiZ",
            "type" : "articles",
            "label" : "sample"
        },
        {
            "id" : "GhkJXpaiZDn59y87P",
            "type" : "articles",
            "label" : "add"
        },
        {
            "id" : "XpaiZDn5GhkJ9y87P",
            "type" : "articles",
            "label" : "External"
        }
    ]
}];


var App = () => {
return (
  <div>
    {
      data.map(e => {
        return (
          <div>
            {
              e.links ? e.links.map(link => {
                return <div dangerouslySetInnerHTML={{ __html: e.content.replace(new RegExp(link.label, 'g'),
                    '<a href="/' + link.id + '">$&</a> (<Icon name="external" />)'
                )}} ></div>
              }) : ''
            }
          </div>
        )
      })
    }
  </div>
)
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>

Sign up to request clarification or add additional context in comments.

3 Comments

But now you're using <a>, not <Link>.
@ChrisG this was an example how to write, Link will not work here so i used a tag, and it is working properly. Same code will work for Link also because Link finally get rendered as a tag only (just a wrapper of a tag) :)
The thing is though, Link will not get rendered as <a>. That's the entire issue in the first place: how to replace part of a string with a React element, as opposed to just text. Only if the string is split into an array, and <Link />s are inserted as elements will it work as expected. Your answer does not address the actual problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.