React-yönlendirici Bağlantısını html düğmesinde sarma


108

Önerilen yöntemi kullanarak: Bu sonucu oluşur: düğmesini bir bağlantı , Kod açıklama satır aralarında

React kullanarak bir HTML etiketinden bir Linköğeyi sarmanın bir yolu olup olmadığını merak ediyordum .'react-router'button

Şu anda Linkuygulamamdaki sayfalarda gezinmek için bileşenlerim var , ancak bu işlevselliği HTML düğmelerimle eşlemek istiyorum.

görüntü açıklamasını buraya girin görüntü açıklamasını buraya girin

Yanıtlar:


165

Bu bir web tarayıcısında oluşturulacak olsa da
şunlara dikkat edin: ⚠️ Bir html'yi buttonbir html içine yerleştirmek a(veya tersi) geçerli html değildir ⚠️. HTML anlamsallığınızı ekran okuyucular için tutmak istiyorsanız, başka bir yaklaşım kullanın.

Ters yönde sarın ve Bağlantı ekli orijinal düğmeyi elde edin. CSS değişikliği gerekmez.

 <Link to="/dashboard">
     <button type="button">
          Click Me!
     </button>
 </Link>

Burada düğme HTML düğmesidir. Semantic-UI-React gibi üçüncü taraf kitaplıklarından içe aktarılan bileşenler için de geçerlidir .

 import { Button } from 'semantic-ui-react'
 ... 
 <Link to="/dashboard">
     <Button style={myStyle}>
        <p>Click Me!</p>
     </Button>
 </Link>

1
Teşekkürler, basit ve çalışıyor, @ChaseJames'in css çözümü çalışmıyor. Belki bir şeyler eksiktir. Ama bootstrap kullanıyorum; import { Button } from 'react-bootstrap';.
Stefano Scarpanti

3
Belgede gezinirken bağlantıya ve ardından düğmeye ayrı ayrı geçersiniz. Bunu önlemek için, Link öğesine tabindex = "- 1" ekleyin. Düğme enter tuşuna basılarak etkinleştirildiğinde bağlantı yine de izlenecektir (en azından Firefox'ta ...).
2017 saat

4
Bildiğiniz gibi, Link bağlantı etiketi oluşturur <a href="">ve bağlantı etiketi düğme etiketi içeremez.
taher

4
Bu işe yarıyor gibi görünse de anlamsal olarak yanlıştır (ve HTML 5'te geçersizdir). Bkz. HTML5 kullanarak bir <a> içine <button> öğesi yerleştirebilir miyim?
imgx64

Örneğin düğmenizi devre dışı bırakırsanız, düğmeye tıklamak yine de çalışacaktır. Bu hacky çözümü history.pushseçeneğe kıyasla kullanmak için gerçekten bir neden yok
Burak

113

LinkButton bileşen - React Router v4 için bir çözüm

İlk olarak, bu soruya verilen diğer birçok cevap hakkında bir not.

⚠️ Nesting <button>ve <a>geçerli html değil. ⚠️

Buradaki herhangi bir yanıt button, bir React Router Linkbileşenine (veya tersi) bir html yerleştirmeyi öneren herhangi bir yanıt , bir web tarayıcısında işlenecektir, ancak bu anlamsal, erişilebilir veya geçerli html değildir:

<a stuff-here><button>label text</button></a>
<button><a stuff-here>label text</a></button>

Bu işaretlemeyi validator.w3.org ile doğrulamak için tıklayın

Düğmeler tipik olarak bağlantıların içine yerleştirilmediğinden bu, düzen / stil sorunlarına yol açabilir.


<button>React Router <Link>bileşeni ile bir html etiketi kullanmak .

Yalnızca bir html buttonetiketi istiyorsanız …

<button>label text</button>

… O zaman, işte React Router'ın Linkbileşeni gibi çalışan bir düğme edinmenin doğru yolu …

Kullanım Yönlendirici Tepki withRouter HOC sizin bileşene bu sahne geçmek:

  • history
  • location
  • match
  • staticContext

LinkButton bileşen

İşte LinkButtonkopyalamanız / makarna için bir bileşen :

// 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)

Ardından bileşeni içe aktarın:

import LinkButton from '/components/LinkButton'

Bileşeni kullanın:

<LinkButton to='/path/to/page'>Push My Buttons!</LinkButton>

Bir onClick yöntemine ihtiyacınız varsa:

<LinkButton
  to='/path/to/page'
  onClick={(event) => {
    console.log('custom event here!', event)
  }}
>Push My Buttons!</LinkButton>

Güncelleme: Yukarıdakiler yazıldıktan sonra sunulan başka bir eğlenceli seçenek arıyorsanız, bu useRouter kancasına göz atın .


13
Kabul edilen cevap bu olmalıdır. Diğer tüm yanıtlar, IMHO, hack'lerdir ve beklenmedik sonuçlar sağlayabilir. Teşekkür ederim!
Kyle

Bileşenin kullanımı <div> .. </divöğesinin içine girer App.jsmi?
DJ2

@ DJ2 - Evet veya onu kullanmak istediğiniz herhangi bir başka bileşende.
Beau Smith

Bunun için teşekkürler! Benim özel kullanım durumumda, bir material-ui butonunu ithal ettim import IconButton from '@material-ui/core/IconButton';ve bunun yerine kullandım <button />ve harika çalıştı.
Dan Evans

1
@Melounek - Merhaba! Hedef <a>görsel olarak bir "düğme" gibi görünecek şekilde tasarlanmış bir html etiketine sahip olmaksa, evet @ChaseJames çözümü bunu başarır. Yukarıdaki soru bir <button>html öğesinin nasıl kullanılacağını sorar <a>.
Beau Smith

36

Neden bağlantı etiketini bir düğmeyle aynı css ile dekore etmiyorsunuz?

<Link 
 className="btn btn-pink"
 role="button"
 to="/"
 onClick={this.handleClick()}
> 
 Button1
</Link>

Bunu son çare olarak tutacağım çünkü ihtiyacım olan tüm düğmeler için CSS yaptırdım ama öneri için teşekkürler
Jose Rivera

Harika çözüm. Plan için şu şekilde yapıyorum: <Link className = {[Classes.BUTTON, Classes.MINIMAL, Classes.ICON + "-" + IconNames.PLUS] .join ("")} to = {"/ link"}> Bağlantı </Link>
caiiiycuk

13

Eğer kullanıyorsanız react-router-domve material-uikullanabilirsiniz ...

import { Link } from 'react-router-dom'
import Button from '@material-ui/core/Button';

<Button component={Link} to="/open-collective">
  Link
</Button>

Daha fazlasını buradan okuyabilirsiniz .


Bu çözüm, todestek Linkzorunlu olduğundan TS ile çalışmayacaktır .
rehber

Bu bir cazibe gibi çalışıyor, teşekkürler
Pedro Silva

11

React-router v5.1.0'dan beri useHistory hook kullanabilirsiniz .

useHistoryKanca size gezinmek için kullanabileceğini tarih örneğine erişim sağlar.

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>
  ...
}

İşleve "bir bağlantı" gönderebilir misin?
Rushino

2020'de bu benim için çalışmıyor. useHistory benim React sürümümde boş
bikeman868

7

Yönlendirici ve <Düğme /> kullanıyorum. <Link /> yok

<Button onClick={()=> {this.props.history.replace('/mypage')}}>
   HERE
</Button>

1
Bunun varsayılan çözüm olması gerektiğini düşünüyorum, ancak belki bazı ayrıntılar benim için kayboldu? Destekleyen HERHANGİ bir bileşen / düğüm / eleman onClick={ () => navigateTo(somePath) }bu yaklaşımı kullanabilir. Cevabınızda olduğu gibi redux ve import {push} from 'connected-react-router'veya sadece history.push(veya değiştir) kullanın.
Thomas Fauskanger

6

5
Bu yüzden bunu denedim ve elde ettiğim şey, merkezde işlevini yerine getiren küçük bir tıklanabilir bağlantıya sahip bir düğmeydi. Ancak düğmede başka herhangi bir yere tıklamak, ancak doğrudan bağlantı hiçbir şey yapmadı.
Jose Rivera

Doğru boyutlandırıldığından emin olmak için düğmenin stilini belirlemek için CSS'yi kullanabilirsiniz. Örneğin, bu kadar ayar widthve height.
Raphael Rafatpanah

2
Satır içi stilleri düğme etiketi için aynı şekilde kullanabilirsiniz. Veya birçok "css in JS" kitaplığından birini kullanabilirsiniz. Tercih ederim styled-components. github.com/styled-components/styled-components
Raphael Rafatpanah

1
Güncellenmiş cevabınızla çalıştı. Çok teşekkür ederim!
Jose Rivera

5
Bu doğru değil ... Düğmeyi sarmalısın, bağlantıyı değil 😱
bensampaio

6

React 16.8+ (kancalar) ve React Router 5 kullanan bir çözüm arayanlar için :

Aşağıdaki koda sahip bir düğmeyi kullanarak rotayı değiştirebilirsiniz:

<button onClick={() => props.history.push("path")}>

React Router, geçmişte <Link to = 'path'> öğesi gibi çalışan push () işlevi de dahil olmak üzere bileşenleriniz için bazı aksesuarlar sağlar .

Bu aksesuarlara erişmek için bileşenlerinizi "withRouter" ile "Higher Order" Bileşeni ile sarmalamanız gerekmez.


Bu benim için iyi çalışıyor; Yine de bu çözümün React 16.8+ veya kancalara özgü olduğundan emin değilim. Bunun BrowserRouteryerine (HTML geçmişi API'sine dayalı olarak) kullandığınız sürece bununla iyi durumda olduğunuzu düşünüyorum HashRouter.
pglezen

5

React Router sürüm 6 güncellemesi:

Buradaki çeşitli cevaplar, react-router'ın evriminin bir zaman çizelgesi gibidir 🙂

React-router v6'daki en son kancaları kullanarak, bu artık useNavigatekanca ile kolayca yapılabilir .

import { useNavigate } from 'react-router-dom'      

function MyLinkButton() {
  const navigate = useNavigate()
  return (
      <button onClick={() => navigate("/home")}>
        Go Home
      </button>
  );
}

3

Biçimlendirilmiş bileşenlerle bu kolayca elde edilebilir

Önce stilize bir düğme tasarlayın

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>
);

kontrol tarz bileşenin evini fazlası için


1

Çözümlerin çoğu işleri karmaşıklaştırmaya odaklandı.

WithRouter'ı kullanmak, Uygulamada başka bir yere bağlanan bir düğme kadar basit bir şey için gerçekten uzun bir çözümdür.

SPA'ya (tek sayfalı uygulama) gidiyorsanız, bulduğum en kolay cevap düğmenin eşdeğer sınıfAdı ile kullanmaktır.

Bu, yaptığınız gibi tüm uygulamanızı yeniden yüklemeden paylaşılan durumu / içeriği korumanızı sağlar

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>

Bu benim için işe yaramadı. Düğmenin hove stili kaybolur v_v.
sbstnssndn

Belki de vurgulu stilleriniz çok kısıtlayıcıdır? Button.myClassName'e atanmışlar mı? Düğmeyi stil seçiciden kaldırın. Veya scss olarak genişletin.
Acts7Seven
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.