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 Link
elemento 'react-router'
en una button
etiqueta HTML usando react.
Actualmente tengo Link
componentes 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.push
opciónLinkButton
componente - 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
button
en unLink
componente 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
button
etiqueta html ...... entonces, esta es la forma correcta de obtener un botón que funcione como el
Link
componente React Router ...Use React Router's withRouter HOC para pasar estos accesorios a su componente:
history
location
match
staticContext
LinkButton
componenteAquí hay un
LinkButton
componente 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> .. </div
elemento 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-dom
ymaterial-ui
puede 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
to
provisiónLink
es obligatoria.Puede usar
useHistory
hook 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
button
en un htmla
(o viceversa) no es un html válidofuente
width
yheight
.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
useNavigate
gancho.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