Dan
Dan

Reputation: 1575

REACT - How to replace URL strings to <a> elements and rendering it properly

Given the following content:

Hi Christine,

Are you receiving?
--
Daniel Vieira Costa.
Frontend Developer | Zeuss, Inc.
Know It's Possible.
http://www.zeuss.com

I want to replace all URL (e.g. http://www.zeuss.com) to <a> elements/objects and render it within a React content.

My base code is the following:

// regular expression used to find out all URL occorrences
let regexpression = /(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$])/ig;

// replace all URL occurrences to <a> elements
content = content.replace(regexpression, newLink => {
    return <a>{newLink}</a>
})

However, the it's rendering the following result:

Hi Christine, 

Are you receiving?
--
Daniel Vieira Costa.
Frontend Developer | Zeuss, Inc.
Know It's Possible.
[object Object]

Where [object Object] should be the <a> element.

I would like to avoid raw HTML with React (setting the dangerouslySetInnerHtml attribute). Is there a better implementation?

Upvotes: 2

Views: 2813

Answers (1)

ChristianM
ChristianM

Reputation: 1823

What you are creating with that syntax is a react element, what oyu want is a string though, so try:

return '<a>' + newLink + '</a>'

You will have to use dangerouslySetInnerHtml anyway as you will have a string with HMTL inside after your replace operation.

Add on answering to the comment:

You might actually get away with doing this by first splitting the string at the URLs, then put it back together in a JSX expression.

So given you manage to split the string into an array like this (should be doable but I leave that part to you):

let splitString = ['Hi Christine,

Are you receiving?
--
Daniel Vieira Costa.
Frontend Developer | Zeuss, Inc.
Know It's Possible.', 'http://www.zeuss.com']

let parsedResult = splitString.map((part) => {
    if (part.matches(regexpression)) {
       return <a>{part}</a>
    }
    return part
})

return <div>{parsedResult}</div>

This should work without using dangerouslySetInnerHtml.

Upvotes: 2

Related Questions