html 버튼에 react-router 링크 감싸기


답변:


165

이것이 웹 브라우저에서 렌더링되지만주의하십시오 :
⚠️ html button에 html 을 중첩 a(또는 그 반대) 하는 것은 유효한 html이 아닙니다 ⚠️. 화면 판독기에 html 의미를 유지하려면 다른 접근 방식을 사용하십시오.

반대로 포장하면 링크가 첨부 된 원래 버튼이 나타납니다. CSS 변경이 필요하지 않습니다.

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

여기 버튼은 HTML 버튼입니다. Semantic-UI-React 와 같은 타사 라이브러리에서 가져온 구성 요소에도 적용 할 수 있습니다.

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

1
감사합니다, 간단하고 작동하지만 @ChaseJames의 CSS 솔루션은 작동하지 않습니다. 뭔가 빠진 것이있을 수도 있습니다. 하지만 저는 부트 스트랩을 사용하고 있습니다. import { Button } from 'react-bootstrap';.
— 스테파노 Scarpanti

3
문서를 탭할 때 앵커로 이동 한 다음 버튼으로 개별적으로 이동합니다. 이를 방지하려면 Link 요소에 tabindex = "-1"을 추가하십시오. Enter 키를 눌러 버튼이 활성화되면 링크가 계속 이어집니다 (적어도 Firefox에서는 ...).
— tremby

4
아시다시피 Link는 앵커 태그를 생성 <a href="">하고 앵커 태그는 버튼 태그를 포함 할 수 없습니다.
— taher

4
이것이 작동하는 것처럼 보이지만 의미 상 잘못되었습니다 (HTML 5에서는 유효하지 않음). HTML5를 사용하여 <a> 안에 <button> 요소를 중첩 할 수 있습니까?를
— imgx64

예를 들어 버튼을 비활성화 한 경우에도 버튼을 클릭해도 작동합니다. history.push옵션 과 비교할 때이 해키 솔루션을 사용할 이유가 없습니다
— Burak

113

LinkButton component-React Router v4 용 솔루션

첫째,이 질문에 대한 다른 많은 답변에 대한 메모입니다.

⚠️ 중첩 <button>되며 <a>유효한 html이 아닙니다. ⚠️

buttonReact Router Link구성 요소에 html 을 중첩하는 것을 제안하는 모든 답변 (또는 그 반대)은 웹 브라우저에서 렌더링되지만 의미 론적이거나 액세스 가능하거나 유효한 html은 아닙니다.

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

☝ 이 마크 업을 validator.w3.org로 확인하려면 클릭하십시오 ☝

일반적으로 버튼이 링크 내부에 배치되지 않기 때문에 레이아웃 / 스타일링 문제가 발생할 수 있습니다.


<button>React Router <Link>구성 요소 와 함께 html 태그 사용 .

html button태그 만 원하는 경우 …

<button>label text</button>

… 그런 다음, React Router의 Link구성 요소 처럼 작동하는 버튼을 얻는 올바른 방법이 있습니다 .

React Router의 withRouter HOC를 사용 하여 이러한 소품을 구성 요소에 전달하십시오.

  • history
  • location
  • match
  • staticContext

LinkButton 구성 요소

LinkButton복사 / 파스타 할 수 있는 구성 요소는 다음과 같습니다 .

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

그런 다음 구성 요소를 가져옵니다.

import LinkButton from '/components/LinkButton'

구성 요소 사용 :

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

onClick 메서드가 필요한 경우 :

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

업데이트 : 위의 내용이 작성된 후 사용할 수있는 또 다른 재미있는 옵션을 찾고 있다면이 useRouter hook을 확인하세요 .


13
이것은 받아 들여진 대답이어야합니다. 다른 모든 대답은 IMHO, 해킹이며 예기치 않은 결과를 제공 할 수 있습니다. 감사합니다!
— Kyle

구성 요소의 사용이 요소 내부 <div> .. </div에 App.js있습니까?
— DJ2

@ DJ2 - 예, 또는 다른 구성 요소에 당신이 그것을 사용하려고합니다.
— 보 스미스

감사합니다! 내 특별한 사용 사례에서 나는 material-ui 버튼을 가져와 import IconButton from '@material-ui/core/IconButton';대신 사용했고 <button />훌륭하게 작동했습니다.
— Dan Evans

1
@Melounek-안녕하세요! 목표가 <a>"버튼"처럼 보이도록 시각적으로 스타일이 지정된 html 태그 를 갖는 것이라면 예 @ChaseJames 솔루션이이를 달성합니다. 위의 질문은 <button>.html이 아닌 html 요소 를 사용하는 방법을 묻습니다 <a>.
— Beau Smith

37

버튼과 동일한 CSS로 링크 태그를 장식하지 않는 이유는 무엇입니까?

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

내가 필요한 모든 버튼에 대해 CSS를 수행했지만 제안 해 주셔서 감사합니다
— Jose Rivera

훌륭한 솔루션. Blueprint의 경우 다음과 같이합니다. <Link className = {[Classes.BUTTON, Classes.MINIMAL, Classes.ICON + "-"+ IconNames.PLUS] .join ( "")} to = { "/ link"}> 링크 </ Link>
— caiiiycuk

13

경우에 당신은 사용 react-router-dom하고 material-ui당신은 사용할 수 있습니다 ...

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

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

여기에서 자세한 내용을 읽을 수 있습니다 .


toprop on Link이 필수 이므로이 솔루션은 TS와 함께 작동하지 않습니다 .
— 디렉토리

이것은 매력처럼 작동합니다. 감사합니다
— Pedro Silva

10

react-router v5.1.0 이후 useHistory 후크 를 사용할 수 있습니다 .

useHistory후크 당신이 탐색하는 데 사용할 수 있다는 것을 역사 인스턴스에 액세스 할 수 있습니다.

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

기능에 "일부 링크"를 푸시 할 수 있습니까?
— Rushino

2020 년에는이 기능이 작동하지 않습니다. useHistory는 내 React 버전에서 null입니다.
— bikeman868

7

라우터와 <버튼 />을 사용합니다. 아니요 <링크 />

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

1
이것이 기본 솔루션이라고 생각하지만 일부 세부 정보가 손실되었을 수 있습니까? 지원하는 모든 구성 요소 / 노드 / 요소는 onClick={ () => navigateTo(somePath) }이 접근 방식을 사용할 수 있습니다. redux를 사용 import {push} from 'connected-react-router'하거나 history.push대답과 같이 그냥 (또는 교체) 여부 .
— Thomas Fauskanger

6

5
그래서 저는 이것을 시도했고, 제가 얻은 것은 그 기능을 수행하는 중앙에 작은 클릭 가능한 링크가있는 버튼이었습니다. 그러나 버튼의 다른 곳을 클릭했지만 직접 링크는 아무것도하지 않았습니다.
— Jose Rivera

CSS를 사용하여 버튼의 스타일을 지정하여 크기가 올바른지 확인할 수 있습니다. 예를 들어, 설정은 width및 height.
— Raphael Rafatpanah

2
버튼 태그에 동일한 방식으로 인라인 스타일을 사용할 수 있습니다. 또는 많은 "JS의 CSS"라이브러리 중 하나를 사용할 수 있습니다. 나는 선호한다 styled-components. github.com/styled-components/styled-components
— 라파엘 Rafatpanah

1
업데이트 된 답변으로 작동했습니다. 정말 고맙습니다!
— Jose Rivera

5
이 정확하지 않습니다 ... 당신은 버튼이 아니라 링크를 😱 포장한다
— bensampaio

6

React 16.8+ (후크) 및 React Router 5를 사용하는 솔루션을 찾는 모든 사람 :

다음 코드로 버튼을 사용하여 경로를 변경할 수 있습니다.

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

React Router는 기록 에 대한 push () 함수를 포함하여 구성 요소에 몇 가지 소품을 제공합니다. <Link to = 'path'> 요소와 매우 유사하게 작동 .

이러한 소품에 액세스하기 위해 상위 구성 요소 "withRouter"로 구성 요소를 래핑 할 필요가 없습니다.


이것은 나를 위해 잘 작동합니다. 이 솔루션이 React 16.8+ 또는 후크에만 해당되는지 잘 모르겠습니다. .NET BrowserRouter대신 HTML 히스토리 API 를 사용하는 한 좋은 상태라고 생각합니다 HashRouter.
— pglezen

3

스타일이 지정된 구성 요소를 사용하면 쉽게 달성 할 수 있습니다.

먼저 스타일이 지정된 버튼 디자인

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

자세한 내용은 스타일 구성 요소의 홈 을 확인하십시오.


3

React Router 버전 6 업데이트 :

여기에있는 다양한 답변은 반응 라우터의 진화 타임 라인과 같습니다 🙂

react-router v6의 최신 후크를 사용하면 이제 useNavigate후크로 쉽게 수행 할 수 있습니다 .

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

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

1

많은 솔루션이 복잡한 문제에 초점을 맞췄습니다.

withRouter를 사용하는 것은 앱의 다른 곳으로 연결되는 버튼처럼 간단한 것을위한 정말 긴 솔루션입니다.

SPA (단일 페이지 응용 프로그램)를 사용하는 경우 가장 쉬운 대답은 버튼의 동등한 className과 함께 사용하는 것입니다.

이렇게하면 다음과 같이 전체 앱을 다시로드하지 않고도 공유 상태 / 컨텍스트를 유지할 수 있습니다.

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>

이것은 나를 위해 작동하지 않았습니다. 버튼의 호브 스타일은 v_v가 손실됩니다.
— sbstnssndn

호버 스타일이 너무 제한적일까요? button.myClassName에 할당되어 있습니까? 스타일 선택기에서 버튼을 제거합니다. 또는 scss에서 확장하십시오.
— Acts7Seven 19
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.