Explain Codes LogoExplain Codes Logo

Wrapping a react-router Link in an HTML button

javascript
prompt-engineering
interview-preparation
best-practices
Alex KataevbyAlex Kataev·Nov 18, 2024
TLDR

Linking together a Link from react-router-dom and a button can be as simple as assigning button-like styles to the Link directly.

import { Link } from 'react-router-dom'; import './Button.css'; // Custom button styles here ... <Link to="/your-route" className="btn"> Click Me </Link> ... /* Button.css */ .btn { display: inline-block; padding: 10px 15px; background-color: #007bff; color: #fff; border-radius: 5px; text-align: center; text-decoration: none; cursor: pointer; }

Voila! You now have a Link styled as a button.

Going deeper: control & semantics

For programmatic navigation while maintaining the button-like design, a combination of a React button and the useHistory hook can be quite handy!

import { useHistory } from 'react-router-dom'; const Button = ({ to }) => { let history = useHistory(); const navigate = () => { history.push(to); // Click me for a fun journey 🚀 }; return <button onClick={navigate}>Click Me</button>; };

By employing the push method, navigation becomes a controllable event, which opens up new possibilities like conditional routing or analytics tracking.

Accessibility first

Maintaining good accessibility standards is crucial. Use semantic HTML and proper ARIA roles to aid users using assistive tech:

<Link to="/your-route" className="btn" role="button" aria-label="Move to destination"> Click Me </Link>

Component based approach

The almighty LinkButton component

If you frequently require this functionality, consider creating a reusable LinkButton component:

import { Link } from 'react-router-dom'; const LinkButton = ({ className, to, children }) => ( <Link to={to} className={`btn ${className}`} role="button"> {children} // Here lie the children of LinkButton 👶 </Link> ); export default LinkButton;

With LinkButton, you've got semantic consistency and a cleaner codebase all in one reusable unit!

How about the style?

Who are you wearing?

With the Link acting as a button, using consistent styling throughout your application becomes a cakewalk:

/* Button styles */ .link-as-button { ... }
<Link to="/your-route" className="link-as-button"> Click Me </Link>

Designer wear: Material-UI

When you're leaning towards libraries like Material-UI, set the component prop as Link. Presto! A perfect combination of react-router and Material-UI!

import Button from '@material-ui/core/Button'; import { Link } from 'react-router-dom'; <Button component={Link} to="/destination"> I'm fashionably functional! 👠 </Button>

Practical advice

Mind your HTML

While wrapping a Link within a button does give the appearance of a button, consider the implications to accessibility and usability. Use tools like validator.w3.org to ensure valid HTML.

Try using a hook

If you lean towards functional components, useRouter offers a much leaner hook-based approach for easy access to routing functions.

The prop filter

While creating a custom LinkButton component, filter out non-button props for a clean button component:

<Link {...otherProps} to={to} className={`btn ${className}`} role="button"> {children} </Link>