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

问题描述 投票:55回答:8

使用建议的方法:This is the result: A link in the buttonCode in between comment lines

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

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

enter image description here enter image description here

html reactjs button hyperlink router
8个回答

102
投票

以相反的方式进行包装,并获得带有链接的原始按钮。无需更改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>

虽然这将在Web浏览器中呈现,但请注意: ⚠️Nesting an html button in an html a (or vice-versa) is not valid html


73
投票

LinkButton component - a solution for React Router v4

首先,关于这个问题的许多其他答案的说明。

⚠️嵌套<button><a>无效的HTML。 ⚠️

这里的任何答案建议在一个React路由器button组件中嵌套一个html Link(反之亦然)将在Web浏览器中呈现,但它不是语义,可访问或有效的html:

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

Click to validate this markup with validator.w3.org

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


使用带有React Router <button>组件的html <Link>标记。

如果你只想要一个html button标签......

<button>label text</button>

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

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

  • history
  • location
  • match
  • staticContext

LinkButton component

这是一个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>

24
投票

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

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

5
投票

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

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

3
投票

如果您使用的是react-router-dommaterial-ui,您可以使用......

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

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

你可以阅读更多here


2
投票

有了风格的组件,这很容易实现

首先设计一个风格的按钮

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

检查styled component's home更多


0
投票

许多解决方案都专注于使事情复杂化。

使用withRouter是一个非常长的解决方案,可以像链接到应用程序中其他位置的按钮一样简单。

如果你要去S.P.A. (单页面应用程序),我发现最简单的答案是使用按钮的等效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>

0
投票

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

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

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

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

您不需要使用高阶组件“withRouter”包装组件以访问这些道具。

© www.soinside.com 2019 - 2024. All rights reserved.