Korzystanie z sugerowanej metody: Oto wynik: łącze w przycisku , kod między wierszami komentarza
Zastanawiałem się, czy istnieje sposób na zawinięcie Link
elementu z tagu 'react-router'
HTML button
za pomocą reakcji.
Obecnie mam Link
komponenty do nawigacji po stronach w mojej aplikacji, ale chciałbym odwzorować tę funkcjonalność na moje przyciski HTML.
import { Button } from 'react-bootstrap';
.<a href="">
kotwicy, a tag kotwicy nie może zawierać tagu przycisku.history.push
opcjąLinkButton
komponent - rozwiązanie dla React Router v4Najpierw uwaga na temat wielu innych odpowiedzi na to pytanie.
⚠️ Zagnieżdżanie
<button>
i<a>
nieprawidłowy kod HTML. ⚠️Każda odpowiedź tutaj, która sugeruje zagnieżdżenie html
button
wLink
komponencie React Router (lub odwrotnie), zostanie wyświetlona w przeglądarce internetowej, ale nie jest semantyczna, dostępna ani poprawna w html:<a stuff-here><button>label text</button></a> <button><a stuff-here>label text</a></button>
☝ Kliknij, aby sprawdzić poprawność tego znacznika za pomocą validator.w3.org ☝
Może to prowadzić do problemów z układem / stylem, ponieważ przyciski zwykle nie są umieszczane w linkach.
Używanie
<button>
tagu html z<Link>
komponentem React Router .Jeśli chcesz tylko
button
tag HTML …… W takim razie oto właściwy sposób na uzyskanie przycisku działającego jak
Link
komponent React Router …Użyj React Router's withRouter HOC, aby przekazać te właściwości do swojego komponentu:
history
location
match
staticContext
LinkButton
składnikOto
LinkButton
komponent do skopiowania / makaronu :// 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)
Następnie zaimportuj komponent:
import LinkButton from '/components/LinkButton'
Użyj komponentu:
<LinkButton to='/path/to/page'>Push My Buttons!</LinkButton>
Jeśli potrzebujesz metody onClick:
<LinkButton to='/path/to/page' onClick={(event) => { console.log('custom event here!', event) }} >Push My Buttons!</LinkButton>
Aktualizacja: Jeśli szukasz innej fajnej opcji dostępnej po napisaniu powyższego, sprawdź ten hook useRouter .
źródło
<div> .. </div
elementuApp.js
?import IconButton from '@material-ui/core/IconButton';
i użyłem go zamiast tego<button />
i działało świetnie.<a>
wizualnie stylizowany tag HTML tak, aby wyglądał jak „przycisk”, to rozwiązanie Yes @ChaseJames pozwala to osiągnąć. Powyższe pytanie dotyczy sposobu użycia<button>
elementu html, a nie pliku<a>
.Dlaczego nie udekorować tagu linku tym samym CSS, co przycisk.
<Link className="btn btn-pink" role="button" to="/" onClick={this.handleClick()} > Button1 </Link>
źródło
Jeśli używasz
react-router-dom
imaterial-ui
możesz użyć ...import { Link } from 'react-router-dom' import Button from '@material-ui/core/Button'; <Button component={Link} to="/open-collective"> Link </Button>
Możesz przeczytać więcej tutaj .
źródło
to
podpórkaLink
jest obowiązkowa.Można użyć
useHistory
haka ponieważ reagują-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> ... }
źródło
Używam routera i <Button />. Nie <Link />
<Button onClick={()=> {this.props.history.replace('/mypage')}}> HERE </Button>
źródło
onClick={ () => navigateTo(somePath) }
może stosować to podejście. Czy używasz Redux iimport {push} from 'connected-react-router'
czy po prostuhistory.push
(lub zamień), jak w Twojej odpowiedzi.⚠️ Nie, zagnieżdżanie html
button
w htmla
(lub odwrotnie) nie jest prawidłowym htmlźródło
width
iheight
.styled-components
. github.com/styled-components/styled-componentsDla każdego, kto szuka rozwiązania wykorzystującego React 16.8+ (hooks) i React Router 5:
Możesz zmienić trasę za pomocą przycisku z następującym kodem:
<button onClick={() => props.history.push("path")}>
React Router zapewnia pewne właściwości dla twoich komponentów, w tym funkcję push () w historii, która działa podobnie jak element <Link to = 'path'>.
Nie musisz opakowywać swoich komponentów komponentem wyższego rzędu „withRouter”, aby uzyskać dostęp do tych właściwości.
źródło
BrowserRouter
(w oparciu o HTML history API) zamiastHashRouter
.Aktualizacja dla React Router w wersji 6:
Różne odpowiedzi tutaj są jak oś czasu ewolucji routera reakcji 🙂
Korzystając z najnowszych hooków z react-router v6, można to teraz łatwo zrobić za pomocą
useNavigate
hooka.import { useNavigate } from 'react-router-dom' function MyLinkButton() { const navigate = useNavigate() return ( <button onClick={() => navigate("/home")}> Go Home </button> ); }
źródło
Dzięki stylowym komponentom można to łatwo osiągnąć
Najpierw zaprojektuj stylizowany przycisk
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> );
sprawdź stronę główną stylizowanego komponentu, aby uzyskać więcej
źródło
Wiele rozwiązań skupiało się na komplikowaniu rzeczy.
Korzystanie z withRouter to naprawdę długie rozwiązanie dla czegoś tak prostego jak przycisk, który prowadzi do innego miejsca w aplikacji.
Jeśli wybierasz się do SPA (aplikacja jednostronicowa), najłatwiejszą odpowiedzią, jaką znalazłem, jest użycie z odpowiednikiem className przycisku.
Zapewnia to utrzymanie udostępnionego stanu / kontekstu bez ponownego ładowania całej aplikacji, tak jak ma to miejsce w przypadku
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>
źródło