Home > database >  In React, how to make <p> tag emulate the behavior of <a> tag?
In React, how to make <p> tag emulate the behavior of <a> tag?

Time:02-22

I have an entire React app built with adding navigation to onClick method of <p> tag, for example: <p onClick={()=>history.push('/contact-us')}>Contact Us</p> (as I didn't want page reload on navigation, something which is expected from SPA). Now the client wants options on right click which the browser provides by default for <a> tag (like open link in new tab, open link in incognito, see image for more details). How can I achieve this by making least amount of change to my code base? The last thing that I would want to do is replace all <p onClick={}> with <a> tag.

CodePudding user response:

Instead of using an tag, it is better to use <NavLink> for links. This behaves like a normal <a> tag but also does not reloads the page (as expected from a SPA).

As for opening the link in a new tab, add these attributes to your : target="_blank" rel="noopener noreferrer". This will open the link in a new tab.

More on that here: https://www.freecodecamp.org/news/how-to-use-html-to-open-link-in-new-tab/#:~:text=The target attribute set to,depending on the browser's settings

CodePudding user response:

Use Link tag you can import from react-router-dom library i.e.,

 import { Link } from 'react-router-dom';

 <Link to={'/contact-us'}>Contact Us</Link>

CodePudding user response:

I build a components that you could customize however you like.

have a look below

import * as React from 'react'
import { Link, useSearchParams, useNavigate } from 'react-router-dom';
import usestate from '@alentoma/usestate';

export const parseLink = (to: string, args?: any[], encryptedArgs?: any[], clean?: boolean) => {
    var url = to;
    args?.forEach(x => {
        var str = (x ?? "").toString();
        if (clean)
            str = x.replace(/[ ]/gmi, "-");
        
        str = encodeURI(str.replace(/\?/gmi, ""));
        url = str.uri(url)
    });
    encryptedArgs?.forEach(x => {
        // encrypt the string you will have t implement this on you own if you use it
        var item = HttpClient.enscriptString(x).toString();
        url = item.uri(url);
    })
    return url;
}

export default ({ clean, className, title, to, children, args, encryptedArgs, onClick, disablenavigation }: { disablenavigation?: boolean, onClick?: Function, clean?: boolean, className?: string, title?: string, to: string, children?: string | JSX.Element | JSX.Element[], args?: string[], encryptedArgs?: string[] }) => {
    const state = usestate({
        path: "",

    })
    const navigate = useNavigate();

    React.useEffect(() => {
        state.path = parseLink(to, args, encryptedArgs, clean);
    }, [])

    return (
        <a className={className} onClick={(e) => {
            e.preventDefault();
            if (onClick != undefined) {
                onClick();
            }
            if (disablenavigation !== true)
                navigate(state.path);
            return false;
        }} title={title} href={state.path}>
            {children}
        </a>
    )
}

Now you could simple do.

<EncryptedLink to='/detail' args={["405"]} title='test title'>
                    <p>
                        Home
                    </p>
</EncryptedLink>

// You could also add click event and navigaion at the same times
<EncryptedLink to='/detail' args={["405"]} onClick={dosomething} title='test title'>
                    <p>
                        Home
                    </p>
</EncryptedLink>

// You could also disable navigation and add click event instead
<EncryptedLink to='/detail' args={["405"]} disablenavigation={true} onClick={dosomething} title='test title'>
                    <p>
                        Home
                    </p>
</EncryptedLink>

  • Related