Usando el método sugerido: Este es el resultado: un enlace en el botón , código entre líneas de comentarios
Me preguntaba si hay una manera de envolver un Linkelemento 'react-router'en una buttonetiqueta HTML usando react.
Actualmente tengo Linkcomponentes para navegar por las páginas de mi aplicación, pero me gustaría asignar esa funcionalidad a mis botones HTML.



import { Button } from 'react-bootstrap';.<a href="">ancla y una etiqueta de ancla no puede contener una etiqueta de botón.history.pushopciónLinkButtoncomponente - una solución para React Router v4Primero, una nota sobre muchas otras respuestas a esta pregunta.
⚠️ Anidado
<button>y<a>no es HTML válido. ⚠️Cualquier respuesta aquí que sugiera anidar un html
buttonen unLinkcomponente React Router (o viceversa) se representará en un navegador web, pero no es un HTML semántico, accesible o válido:<a stuff-here><button>label text</button></a> <button><a stuff-here>label text</a></button>☝ Haga clic para validar este marcado con validator.w3.org ☝
Esto puede provocar problemas de diseño / estilo, ya que los botones no suelen colocarse dentro de los enlaces.
Usando una
<button>etiqueta html con el<Link>componente React Router .Si solo desea una
buttonetiqueta html ...... entonces, esta es la forma correcta de obtener un botón que funcione como el
Linkcomponente React Router ...Use React Router's withRouter HOC para pasar estos accesorios a su componente:
historylocationmatchstaticContextLinkButtoncomponenteAquí hay un
LinkButtoncomponente para que lo copie / 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)Luego importe el componente:
import LinkButton from '/components/LinkButton'Utilice el componente:
<LinkButton to='/path/to/page'>Push My Buttons!</LinkButton>Si necesita un método onClick:
<LinkButton to='/path/to/page' onClick={(event) => { console.log('custom event here!', event) }} >Push My Buttons!</LinkButton>Actualización: si está buscando otra opción divertida disponible después de que se escribió lo anterior, consulte este enlace useRouter .
fuente
<div> .. </divelemento deApp.js?import IconButton from '@material-ui/core/IconButton';y lo usé en lugar de<button />y funcionó muy bien.<a>etiqueta html diseñada visualmente para que parezca un "botón", entonces sí, la solución @ChaseJames lo logra. La pregunta anterior pregunta cómo usar un<button>elemento html, no un<a>.¿Por qué no decorar la etiqueta de enlace con el mismo CSS que un botón?
<Link className="btn btn-pink" role="button" to="/" onClick={this.handleClick()} > Button1 </Link>fuente
Si está usando
react-router-domymaterial-uipuede usar ...import { Link } from 'react-router-dom' import Button from '@material-ui/core/Button'; <Button component={Link} to="/open-collective"> Link </Button>Puedes leer más aquí .
fuente
toprovisiónLinkes obligatoria.Puede usar
useHistoryhook desde react-router v5.1.0 .import React from 'react' import { useHistory } from 'react-router' export default function SomeComponent() { const { push } = useHistory() ... <button type="button" onClick={() => push('/some-link')} > Some link </button> ... }fuente
Yo uso Router y <Button />. No <Enlace />
<Button onClick={()=> {this.props.history.replace('/mypage')}}> HERE </Button>fuente
onClick={ () => navigateTo(somePath) }podría utilizar este enfoque. Ya sea que use redux yimport {push} from 'connected-react-router'o simplementehistory.push(o reemplace) como en su respuesta.⚠️ No, anidar un html
buttonen un htmla(o viceversa) no es un html válidofuente
widthyheight.styled-components. github.com/styled-components/styled-componentsPara cualquiera que busque una solución con React 16.8+ (ganchos) y React Router 5:
Puedes cambiar la ruta usando un botón con el siguiente código:
<button onClick={() => props.history.push("path")}>React Router proporciona algunos accesorios a sus componentes, incluida la función push () en el historial que funciona de manera muy similar al elemento <Link to = 'path'>.
No es necesario que envuelva sus componentes con el Componente de orden superior "withRouter" para obtener acceso a esos accesorios.
fuente
BrowserRouter(basado en la API de historial HTML) en lugar deHashRouter.Con componentes de estilo, esto se puede lograr fácilmente
Primero diseñe un botón con estilo
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> );comprobar la casa del componente de estilo para más
fuente
Actualización para React Router versión 6:
Las diversas respuestas aquí son como una línea de tiempo de la evolución de react-router 🙂
Usando los últimos ganchos de react-router v6, esto ahora se puede hacer fácilmente con el
useNavigategancho.import { useNavigate } from 'react-router-dom' function MyLinkButton() { const navigate = useNavigate() return ( <button onClick={() => navigate("/home")}> Go Home </button> ); }fuente
Muchas de las soluciones se han centrado en complicar las cosas.
Usar withRouter es una solución realmente larga para algo tan simple como un botón que se vincula a otra parte de la aplicación.
Si opta por SPA (aplicación de una sola página), la respuesta más fácil que he encontrado es usarla con el className equivalente del botón.
Esto asegura que mantiene el estado / contexto compartido sin recargar toda la aplicación como se hace con
import { NavLink } from 'react-router-dom'; // 14.6K (gzipped: 5.2 K) // Where link.{something} is the imported data <NavLink className={`bx--btn bx--btn--primary ${link.className}`} to={link.href} activeClassName={'active'}> {link.label} </NavLink> // Simplified version: <NavLink className={'bx--btn bx--btn--primary'} to={'/myLocalPath'}> Button without using withRouter </NavLink>fuente