在 html 按钮中包装一个反应路由器链接

使用建议的方法: 这就是结果: 按钮 中的一个链接, 注释行之间的代码

我想知道是否有一种方法可以使用 response 在 HTML button标记中包装来自 'react-router'Link元素。

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

enter image description here enter image description here

323008 次浏览

为什么不把链接标签装饰成和按钮一样的 css 呢。

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

虽然这会在浏览器中呈现,但要注意:
Something 将 html ABC0嵌套在 html a(反之亦然) < strong > 中是无效的 html something. 如果希望将 HTML 语义保留给屏幕阅读器,请使用另一种方法。

用相反的方式进行包装,你会得到原来的按钮与链接附加。没有 CSS 需要改变。

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

这里的按钮是 HTML 按钮。它也适用于从第三方库导入的组件,如 语义-用户界面-反应

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

LinkButton组件-反应路由器 v4的解决方案

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

Something 嵌套 <button><a>是无效的 html。 something

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

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

Something 单击以验证此标记的 validator.w3.org something

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


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

如果您只想要一个 html button标记..。

<button>label text</button>

... 然后,这里有一个正确的方法得到一个按钮,像反应路由器的 Link组件的工作..。

使用反应路由器的 路由器 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>

更新: 如果你正在寻找另一个有趣的选项,在上面写完之后,看看这个 用路由器挂钩

我使用路由器和 < Button/> . No < Link/>

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

使用样式化的组件可以很容易地实现这一点

首先设计一个样式化的按钮

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

检查 风格化组件的家获得更多信息

如果您正在使用 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>

你可以阅读更多的 给你

许多解决方案都把重点放在复杂的事情上。

对于一些简单的事情,比如一个按钮链接到应用程序的其他地方,使用 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>

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

您可以使用下面的代码按钮更改路由:

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

React Router 为您的组件提供了 一些支持,包括 历史上的 推()函数,其工作原理非常类似于 < Link to = ‘ path’> 元素。

您不需要用较高顺序组件“ withRouter”包装您的组件来访问这些道具。

可以从 反应路由器 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>
...
}

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

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

结论: 处理这个问题的更好方法是使用 <a>标签并对其进行样式化。

React 路由器版本6的更新:

这里的各种答案就像是一个反应路由器演化的时间线

使用最新的钩子从反应路由器 v6,这现在可以很容易地与 useNavigate钩子。

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


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

我建议您在 Link组件上使用 component道具。使用这种方法,您可以从 React Rotuer 的角度有效地让任何组件作为 a组件行事。例如,您可以创建自己的“ Button”组件,然后利用它。


const MyButton = () => {
return <button>Do something with props, etc.</button>
}


<Link to="/somewhere" component={MyButton}>Potentially pass in text here</Link>

使用 react-router-dom和函数

作为反应,您可以通过应用 useHistory调用来使用 react-router-dom..。

首先

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

其次 在你的函数中... 写一个函数来处理按钮的点击

const handleButtonClick = () => {
history.push('/YourPageLink')
}

最后

<button onClick={handleButtonClick} className="CSS">
Button Text
</button>
<Button component={Link} to="/dashboard" type="button">
Click Me!
</Button>

当我搜索答案时,每个人都在谈论旧版本的 response-router-dom,所以对于那些想在函数组件中使用钩子的人来说,这可能是一个有用的答案。与新版本一样,只有很少的钩子被更改,甚至 withRouter 也不适用,您需要制作一个自定义 HOC。

我们可以通过功能组件实现它,您可以使用您的按钮,然后描述 onClick 事件,通过 useNavigatehook 触发到下一个页面。

React-路由器-Dom 版本6


这只有在功能组件中才有可能,因为我正在使用钩子,如果你想在类组件中使用,那么你可以使用 hoc。

import {Link, useNavigate} from 'react-router-dom';
function Home() {
you can pass your state like so:  navigate('/show',{state});
const toShowInfoPage=()=>{
navigate('/show');


}




return(
<>




/*you can use button as well or anything
of your choice, but remember
you have to pass the onClick event.
*/
<a
onClick={()=>{toShowInfoPage()}}
style=\{\{textDecoration:'none',
paddingRight:'20px',
color:'#187bcd',
cursor:'pointer'}}>




</>


)






}

要使用类组件访问 useNavigate () ,您必须要么转换为函数组件,要么滚动自定义的 withRouter Higher Order Component 来注入“路由道具”,就像 react-router-dom v5.x 中的 withRouter HOC 所做的那样。


这只是一个大概的想法。 如果你想使用导航这里有一个自定义 withRouter HOC 的例子:

const withRouter = WrappedComponent => props => {
const params = useParams();
// etc... other react-router-dom v6 hooks


return (
<WrappedComponent
{...props}
params={params}
// etc...
/>
);
};

并用新的 HOC 装饰组件。

export default withRouter(Post);

这将为 class 组件注入一个 props

您可以使用 component道具: https://v5.reactrouter.com/web/api/Link/component-reactcomponent

例如:

<Link to="/login" component={({ navigate}) => <button onClick={navigate}>Login</button>} />