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 ⚠️.
If you want to keep your html semantic to screen readers, use another approach.
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>
LinkButton
component - a solution for React Router v4First, a note about many other answers to this question.
<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.
<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
componentHere’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>
Update: If you're looking for another fun option made available after the above was written, check out this useRouter hook.
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>
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.
You can use useHistory
hook since react-router v5.1.0.
The
useHistory
hook gives you access to the history instance that you may use to navigate.
import React from 'react'
import { useHistory } from 'react-router-dom'
export default function SomeComponent() {
const { push } = useHistory()
...
<button
type="button"
onClick={() => push('/some-link')}
>
Some link
</button>
...
}
NOTE: be aware that this approach answers the question but is not accessible like @ziz194 says in their comment
this is not accessible though, as the button will not be a tag and thus it doesn't have link behaviours, like opening the link in a new page. It is also not optimal for screen readers.
I use Router and < Button/>. No < Link/>
<Button onClick={()=> {this.props.history.replace('/mypage')}}>
HERE
</Button>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With