I have a sentence: "This is a sentence with a link1, also it has link2" It is in p tag. I also have data when it starts and when it ends, respectively:
[{ start: 26, end: 31 }, { start: 45, end: 50 }]
Is it possible to replace these parts of the sentence with anchor tags having upper data available. As a result it would be a something like this:
<p>This is a sentence with a <a>link1</a>, also it has <a>link2</a></p>
Thanks!
Building a string of HTML and/or using dangerouslySetInnerHTML
is not the correct solution here. To solve this the "React way," consider that this structure:
<p>This is a sentence with a <a>link1</a>, also it has <a>link2</a></p>
...could be generated with this React component (this is more verbose than necessary, just for clarity's sake):
const LinkText = () => {
const parts = [
'This is a sentence with a ',
<a>{'link1'}</a>,
', also it has ',
<a>{'link2'}</a>,
];
return <p>{parts}</p>;
};
With that in mind, the question is this: How do we generate the parts
array from a string and an array of link positions? The solution is to iterate over the array of link positions and, in each iteration, push onto the array 1) The "non-link" text between the previous link position's end
(or the start of the string), and 2) an <a>
containing the current link position's start
and end
. A simple, working implementation looks like this:
const LinkText = ({ text, linkPositions }) => { const parts = []; let currentIndex = 0; linkPositions.forEach(({ start, end }) => { if (currentIndex < start) { parts.push(text.slice(currentIndex, start)); } parts.push(<a>{text.slice(start, end)}</a>); currentIndex = end; }); if (currentIndex < text.length - 1) { parts.push(text.slice(currentIndex)); // Remaining text after the last link } return <p>{parts}</p>; }; const text = 'This is a sentence with a link1, also it has link2'; const links = [{ start: 26, end: 31 }, { start: 45, end: 50 }]; ReactDOM.render(<LinkText text={text} linkPositions={links}/>, document.querySelector('div'));
a{color:blue}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div></div>
The best way to do that is using IDs and JS.
So, for example, your HTML would look like this:
<p>This is a sentence with a <a id="linkOne">link1</a>, also it has <a id="linkTwo">link2</a></p>
And then your JS would call this:
document.getElementById("linkOne").href = "http://linkOne.com"
document.getElementById("linkTwo").href = "http://linkTwo.com"
You can achieve that with str.replace
with a regex.
as @Dupocas said, React will escape html tags, so you will need to use dangerouslySetInnerHTML
const str = 'This is a sentence with a link1, also it has link2'; const result = str.replace(/link(\\d)/g, (match, linkId) => { return `<a href="${linkId}">${match}</a>`; }); console.log(result);
You can use this snippet to replace the text at the specific places into links. I have sorted it in a descending order based on the start since changing it from the end of the string is easier.
document.getElementById("convert").addEventListener("click", convertLinks); addEventListener function convertLinks() { var pTag = document.getElementById("test") var text = pTag.innerHTML posData = [{ start: 26, end: 31 }, { start: 45, end: 50 }] posData = posData.sort(function(pos1, pos2) { return pos2.start - pos1.start }) for (pos of posData) { text = replaceLink(text, pos) } pTag.innerHTML = text; } function replaceLink(text, pos) { return text.slice(0, pos.start) + "<a>" + text.slice(pos.start, pos.end) + "</a>" + text.slice(pos.end) }
a { color: blue }
<p id="test">This is a sentence with a link1, also it has link2</p> <button id="convert"> Convert Links </button>
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.