En utilisant la méthode suggérée: Voici le résultat: Un lien dans le bouton , Code entre les lignes de commentaire
Je me demandais s'il existe un moyen d'envelopper un Link
élément 'react-router'
dans une button
balise HTML en utilisant react.
J'ai actuellement des Link
composants pour naviguer dans les pages de mon application, mais je voudrais mapper cette fonctionnalité à mes boutons HTML.
import { Button } from 'react-bootstrap';
.<a href="">
ancrage et la balise d'ancrage ne peut pas contenir de balise de bouton.history.push
optionLinkButton
composant - une solution pour React Router v4Tout d'abord, une note sur de nombreuses autres réponses à cette question.
⚠️ Nesting
<button>
et<a>
n'est pas valide html. ⚠️Toute réponse ici suggérant d'imbriquer un html
button
dans unLink
composant React Router (ou vice-versa) sera rendue dans un navigateur Web, mais ce n'est pas un html sémantique, accessible ou valide:<a stuff-here><button>label text</button></a> <button><a stuff-here>label text</a></button>
☝ Cliquez pour valider ce balisage avec validator.w3.org ☝
Cela peut entraîner des problèmes de mise en page / de style, car les boutons ne sont généralement pas placés à l'intérieur des liens.
Utilisation d'une
<button>
balise html avec le<Link>
composant React Router .Si vous voulez uniquement une
button
balise HTML …… Alors, voici la bonne façon d'obtenir un bouton qui fonctionne comme le
Link
composant de React Router …Utilisez le withRouter HOC de React Router pour transmettre ces accessoires à votre composant:
history
location
match
staticContext
LinkButton
composantVoici un
LinkButton
composant à copier / pâtes :// 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)
Importez ensuite le composant:
import LinkButton from '/components/LinkButton'
Utilisez le composant:
<LinkButton to='/path/to/page'>Push My Buttons!</LinkButton>
Si vous avez besoin d'une méthode onClick:
<LinkButton to='/path/to/page' onClick={(event) => { console.log('custom event here!', event) }} >Push My Buttons!</LinkButton>
Mise à jour: Si vous recherchez une autre option amusante disponible après l'écriture de ce qui précède , consultez ce hook useRouter .
la source
<div> .. </div
élément deApp.js
?import IconButton from '@material-ui/core/IconButton';
et je l'ai utilisé à la place de<button />
et cela a très bien fonctionné.<a>
balise html visuellement stylisée pour ressembler à un "bouton", alors oui, la solution @ChaseJames y parvient. La question ci-dessus demande comment utiliser un<button>
élément html, pas un<a>
.Pourquoi ne pas simplement décorer la balise de lien avec le même CSS qu'un bouton.
<Link className="btn btn-pink" role="button" to="/" onClick={this.handleClick()} > Button1 </Link>
la source
Si vous utilisez
react-router-dom
et quematerial-ui
vous pouvez utiliser ...import { Link } from 'react-router-dom' import Button from '@material-ui/core/Button'; <Button component={Link} to="/open-collective"> Link </Button>
Vous pouvez en savoir plus ici .
la source
to
prop onLink
est obligatoire.Vous pouvez utiliser
useHistory
hook depuis 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> ... }
la source
J'utilise Router et <Button />. Non <Link />
<Button onClick={()=> {this.props.history.replace('/mypage')}}> HERE </Button>
la source
onClick={ () => navigateTo(somePath) }
pourrait utiliser cette approche. Que ce soit en utilisant redux etimport {push} from 'connected-react-router'
ou simplementhistory.push
(ou remplacer) comme dans votre réponse.⚠️ Non, l' imbrication d'un html
button
dans un htmla
(ou vice-versa) n'est pas un html validela source
width
etheight
.styled-components
. github.com/styled-components/styled-componentsPour tous ceux qui recherchent une solution utilisant React 16.8+ (hooks) et React Router 5:
Vous pouvez modifier l'itinéraire à l'aide d'un bouton avec le code suivant:
<button onClick={() => props.history.push("path")}>
React Router fournit quelques accessoires à vos composants, y compris la fonction push () sur l' historique qui fonctionne à peu près comme l'élément <Link to = 'path'>.
Vous n'avez pas besoin d'encapsuler vos composants avec le composant d'ordre supérieur "withRouter" pour accéder à ces accessoires.
la source
BrowserRouter
(basé sur l'API de l'historique HTML) au lieu deHashRouter
.Avec des composants stylisés, cela peut être facilement réalisé
Commencez par concevoir un bouton stylé
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> );
consultez la maison du composant stylisé pour en savoir plus
la source
Mise à jour pour React Router version 6:
Les différentes réponses ici sont comme une chronologie de l'évolution de React-Router 🙂
En utilisant les derniers hooks de react-router v6, cela peut maintenant être fait facilement avec le
useNavigate
hook.import { useNavigate } from 'react-router-dom' function MyLinkButton() { const navigate = useNavigate() return ( <button onClick={() => navigate("/home")}> Go Home </button> ); }
la source
Bon nombre des solutions se sont concentrées sur la complication des choses.
Utiliser withRouter est une solution très longue pour quelque chose d'aussi simple qu'un bouton qui renvoie à un autre endroit de l'application.
Si vous optez pour SPA (application d'une seule page), la réponse la plus simple que j'ai trouvée est de l'utiliser avec le nom de classe équivalent du bouton.
Cela garantit que vous maintenez l'état / le contexte partagé sans recharger l'intégralité de votre application, comme c'est le cas avec
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>
la source