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> .. </divApp.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를 사용하여 버튼의 스타일을 지정하여 크기가 올바른지 확인할 수 있습니다. 예를 들어, 설정은 widthheight.
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.