在html按钮中包含react-router链接

Jos*_*era 68 html router button hyperlink reactjs

使用建议的方法: 结果如下:按钮中的链接, 注释行之间的代码

我想知道是否有办法使用react 包装HTML 标签中的Link元素.'react-router'button

我目前Link在我的应用程序中有导航页面的组件,但我想将该功能映射到我的HTML按钮.

在此输入图像描述 在此输入图像描述

Nar*_*ula 113

以相反的方式进行包装,并获得带有链接的原始按钮.无需更改CSS.

 <Link to="/dashboard">
     <button type="button">
          Click Me!
     </button>
 </Link>
Run Code Online (Sandbox Code Playgroud)

这里的按钮是HTML按钮.它也适用于从Semantic-UI-React等第三方库导入的组件.

 import { Button } from 'semantic-ui-react'
 ... 
 <Link to="/dashboard">
     <Button style={myStyle}>
        <p>Click Me!</p>
     </Button>
 </Link>
Run Code Online (Sandbox Code Playgroud)

  • 如您所知,Link创建锚标记`<a href="">`,锚标记不能包含按钮标记. (4认同)
  • 虽然这似乎有效,但它在语义上是错误的(在HTML 5中无效).请参阅[我可以使用HTML5在<a>中嵌套<button>元素吗?](/sf/ask/447567921/使用-HTML5/6393863#6393863) (4认同)
  • 在标签浏览文档时,您将选中标签到锚点,然后单独按钮.要避免这种情况,请将tabindex =" - 1"添加到Link元素.当按下Enter键激活按钮时,仍将遵循该链接(至少在Firefox中). (2认同)
  • 例如,如果您禁用按钮,单击该按钮仍然有效。与“history.push”选项相比,确实没有理由使用这种黑客解决方案 (2认同)

Bea*_*ith 87

LinkButton 组件 - React Router v4的解决方案

将一个html嵌套<button>在一个React Router <a>组件中(反之亦然)可以工作......但是这是一个hack ...而且你得到了html嵌套,没有人应该写:

<a stuff-here><button>label text</button></a>
<button><a stuff-here>label text</a></button>
Run Code Online (Sandbox Code Playgroud)

这可能导致布局/样式问题,因为按钮通常不放置在链接内.

你真正想要的HTML只是一个button标签:

<button>label text</button>
Run Code Online (Sandbox Code Playgroud)

这是获得像React Router的Link组件一样工作的按钮的正确方法......

使用React Router的withRouter HOC将这些道具传递给您的组件:

  • <button>
  • <Link>
  • button
  • Link

history 零件

这是location你复制/ 面食的一个组件:

// 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)
Run Code Online (Sandbox Code Playgroud)

然后导入组件:

import LinkButton from '/components/LinkButton'
Run Code Online (Sandbox Code Playgroud)

使用组件:

<LinkButton to='/path/to/page'>Push My Buttons!</LinkButton>
Run Code Online (Sandbox Code Playgroud)

如果需要onClick方法:

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

  • 这应该是公认的答案.所有其他答案是,恕我直言,黑客,并可以提供意想不到的结果.谢谢! (13认同)
  • 但是您不能在此处使用 &lt;a&gt; 功能,例如 Ctrl+Click 或在单击之前在页脚中查看目标 url :( 我投票支持 @ChaseJames 解决方案作为最干净的解决方案。 (2认同)

Cha*_*mes 28

为什么不用与按钮相同的css来装饰链接标签.

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

  • 您不能在假按钮上使用启用/禁用状态。 (3认同)

San*_*ues 23

react-router v5.1.0以来,您可以使用useHistory 钩子

useHistory挂钩使您可以访问可用于导航的历史记录实例。

import React from 'react'
import { useHistory } from 'react-router-dom'

export default function SomeComponent() {
  const { push } = useHistory()
  ...
  <button
    type="button"
    onClick={() => push('/some-link')}
  >
    Some link
  </button>
  ...
}
Run Code Online (Sandbox Code Playgroud)

注意:请注意,这种方法可以回答问题,但无法像@ziz194 在他们的评论中所说的那样访问

但是这是不可访问的,因为按钮不是标签,因此它没有链接行为,例如在新页面中打开链接。它对于屏幕阅读器也不是最佳选择。

  • 在react-router-dom版本6中,您无法使用useHistory,而是可以使用useNavigate。 (2认同)

Rap*_*nah 6

?? 不,在 htmlbutton中嵌套html a(反之亦然)不是有效的 html

  • 所以我尝试了这个,我得到的是一个按钮,中间有一个可点击的小链接,起到了它的作用。然而,点击按钮上的其他任何地方,但直接链接什么也没做。 (5认同)
  • 这不正确......你应该包装按钮,而不是链接 (5认同)
  • 您可以以与按钮标记相同的方式使用内联样式。或者您可以使用众多“JS 中的 css”库之一。我更喜欢`styled-components`。https://github.com/styled-components/styled-components (2认同)

Ala*_*lan 6

我使用Router和<Button />.没有<Link />

<Button onClick={()=> {this.props.history.replace('/mypage')}}>
   HERE
</Button>
Run Code Online (Sandbox Code Playgroud)

  • 我认为这应该是默认解决方案,但也许我丢失了一些细节?_ANY_ 支持 `onClick={ () =&gt; navigateTo(somePath) }` 的组件/节点/元素可以使用这种方法。无论是使用 redux 和 `import {push} from 'connected-react-router'` 还是只使用 `history.push`(或替换),就像你的答案一样。 (2认同)

Pau*_*evy 6

对于使用React 16.8+(钩子)和 React Router 5寻找解决方案的任何人:

您可以使用带有以下代码的按钮更改路线:

<button onClick={() => props.history.push("path")}>
Run Code Online (Sandbox Code Playgroud)

React Router 为您的组件提供了一些道具,包括历史上push()函数,它的工作方式与 < Link to='path' > 元素非常相似。

你不需要用高阶组件“withRouter”包装你的组件来访问这些道具。


Obe*_*bed 5

使用样式组件可以轻松实现

首先设计一个样式按钮

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>
);
Run Code Online (Sandbox Code Playgroud)

检查样式组件的主页以获取更多信息


Ina*_*Huq 5

如果您正在使用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>
Run Code Online (Sandbox Code Playgroud)

您可以在这里阅读更多内容。


小智 5

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>
  );
}
Run Code Online (Sandbox Code Playgroud)

  • 版本 6 尚不可用,因此这个答案令人困惑。截至此评论的最新版本是 5.2.0。 (3认同)