html - example - react-router-dom external link




Wrapping a react-router Link in an html button (6)

Using suggested method: This is the result: A link in the button , Code in between comment lines

I was wondering if there is a way to wrap a Link element from 'react-router' in an HTML button tag using react.

I currently have Link components to navigate pages in my app, but I would like to map that functionality to my HTML buttons.


LinkButton component - a solution for React Router v4

First, a note about many other answers to this question.

⚠️ Nesting <button> and <a> is not valid html. ⚠️

Any answer here which suggests nesting a html button in a React Router Link component (or vice-versa) will render in a web browser, but it is not semantic, accessible, or valid html:

<a stuff-here><button>label text</button></a>
<button><a stuff-here>label text</a></button>

Click to validate this markup with validator.w3.org

This can lead to layout/styling issues as buttons are not typically placed inside links.

Using an html <button> tag with React Router <Link> component.

If you only want an html button tag…

<button>label text</button>

…then, here's the right way to get a button that works like React Router’s Link component…

Use React Router’s withRouter HOC to pass these props to your component:

  • history
  • location
  • match
  • staticContext

LinkButton component

Here’s a LinkButton component for you to copy/ pasta :

// file: /components/LinkButton.jsx
import React from 'react'
import PropTypes from 'prop-types'
import { withRouter } from 'react-router'

const LinkButton = (props) => {
  const {
    history,
    location,
    match,
    staticContext,
    to,
    onClick,
    // ⬆ filtering out props that `button` doesn’t know what to do with.
    ...rest
  } = props
  return (
    <button
      {...rest} // `children` is just another prop!
      onClick={(event) => {
        onClick && onClick(event)
        history.push(to)
      }}
    />
  )
}

LinkButton.propTypes = {
  to: PropTypes.string.isRequired,
  children: PropTypes.node.isRequired
}

export default withRouter(LinkButton)

Then import the component:

import LinkButton from '/components/LinkButton'

Use the component:

<LinkButton to='/path/to/page'>Push My Buttons!</LinkButton>

If you need an onClick method:

<LinkButton
  to='/path/to/page'
  onClick={(event) => {
    console.log('custom event here!', event)
  }}
>Push My Buttons!</LinkButton>

Do wrapping in the reverse way and you get the original button with the Link attached. No CSS changes required.

 <Link to="/dashboard">
     <button type="button">
          Click Me!
     </button>
 </Link>

Here button is HTML button. It is also applicable to the components imported from third party libraries like Semantic-UI-React .

 import { Button } from 'semantic-ui-react'
 ... 
 <Link to="/dashboard">
     <Button style={myStyle}>
        <p>Click Me!</p>
     </Button>
 </Link>

While this will render in a web browser, beware that:
⚠️ Nesting an html button in an html a (or vice-versa) is not valid html


I use Router and < Button/>. No < Link/>

<Button onClick={()=> {this.props.history.replace('/mypage')}}>
   HERE
</Button>

If you are using react-router-dom and material-ui you can use ...

import { Link } from 'react-router-dom'
import Button from '@material-ui/core/Button';

<Button component={Link} to="/open-collective">
  Link
</Button>

You can read more here .


Why not just decorate link tag with the same css as a button.

<Link 
 className="btn btn-pink"
 role="button"
 to="/"
 onClick={this.handleClick()}
> 
 Button1
</Link>

With styled components this can be easily achieved

First Design a styled button

import styled from "styled-components";
import {Link} from "react-router-dom";

const Button = styled.button`
  background: white;
  color:red;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid red;
  border-radius: 3px;
`
render(
    <Button as={Link} to="/home"> Text Goes Here </Button>
);

check styled component's home for more







router