简体   繁体   中英

How to convert all email addresses to links and put them into a React component?

I have the following code in one my components:

return <Box>{props.children}</Box>

All this does is return the contents in a nicely formatted <div> box. Now what I want to do is if there are any email addresses in props.children , I want to render those as links. So for example, if the content was as follows:

Hi my name is Foo, you can contact me at foo@bar.com.

Then I would like the component to return this:

<div class="box">
  Hi my name is Foo, you can contact me at <a href="mailto:foo@bar.com">foo@bar.com</a>.
<div>

How do I do this? I was thinking of using regex to find all email addresses and add the <a> tags to them, but that didn't seem to work. Any help is appreciated here!

You can use regex

const str = `Hi my name is Foo, you can contact me at foo@bar.com, foo@yan.net`;


console.log(str.replace(/(\w+@\w+.\w+)+/g, "<a href='mailto:$1'>$1</a>"));

Output:

"Hi my name is Foo, you can contact me at <a href='mailto:foo@bar.com'>foo@bar.com</a>, <a href='mailto:foo@yan.net'>foo@yan.net</a>"

I am assuming that " props.chaildren " text has only one email.

import React from 'react';

function isContainEmail() {
    //Write your logic to find this and I am assuming this function will return email address otherwise null
    return 'foo@bar.com';
}
function splitByEmail() {
    //  Do your logic to split the email from text and send both part in a array
    return [
        'Hi my name is Foo, you can contact me at',
        '. Some others line go here',
    ];
}
function generateTemplateForUser(text) {
    const email = isContainEmail(text);
    if (!email) return <div className='box'>{text}</div>;
    const linkProps = {
        href: `mailto:${email}`,
    };
    const textSplittedByEmail = splitByEmail(text);
    return (
        <div className='box'>
            {textSplittedByEmail[0]} <a {...linkProps}> {email}</a>
            {textSplittedByEmail[1]}
        </div>
    );
}
function App(props) {
    return (
        <>
            {/* Please pass your props.children value in place of hardcoded value */}
            {generateTemplateForUser(
                'Hi my name is Foo, you can contact me at foo@bar.com. Some others line go here....',
            )}
        </>
    );
}

export default App;

This solution will not work if you can have multiple emails in your text. Feel free to comment if you have any doubts.

Update

If you have multiple emails in text, then please use html-react-parser .

import React from 'react';
import parser from 'html-react-parser';
// Copy from @denelvis's answer
const formatText = (text) => {
  return text.replace(/(\w+@\w+.\w+)+/g, "<a href='mailto:$1'>$1</a>");
};
function App(props) {
  return (
    <>
      {/* Please pass your props.children value in place of hardcoded value */}
      {parser(
        formatText(
          'Hi my name is Foo, you can contact me at foo@bar.com. Some others line go here.Hi my name is Dummy, you can contact me at foo@bar.com'
        )
      )}
    </>
  );
}

export default App;

Stackblitz Link

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