簡體   English   中英

在 html 按鈕中包裝 react-router 鏈接

[英]Wrapping a react-router Link in an html button

使用建議的方法:結果如下:按鈕中的鏈接注釋行之間的代碼

我想知道是否有一種方法可以使用 react 將來自'react-router'Link元素包裝在 HTML button標簽中。

我目前有Link組件來導航我的應用程序中的頁面,但我想 map 該功能到我的 HTML 按鈕。

在此處輸入圖像描述 在此處輸入圖像描述

雖然這將在 Web 瀏覽器中呈現,但請注意:
⚠️ 在 html a嵌套 html button (反之亦然)是無效的 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>

LinkButton組件 - React Router v4 的解決方案

首先,關於這個問題的許多其他答案的說明。

⚠️ 嵌套<button><a>不是有效的 html。 ⚠️

此處任何建議在 React Router Link組件中嵌套 html button (或反之亦然)的答案都將在 Web 瀏覽器中呈現,但它不是語義、可訪問或有效的 html:

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

單擊以使用validator.w3.org 驗證此標記

這可能會導致布局/樣式問題,因為按鈕通常不會放置在鏈接內。


在 React Router <Link>組件中使用 html <button>標簽。

如果你只想要一個 html button標簽......

<button>label text</button>

……那么,這是獲得一個像 React Router 的Link組件一樣工作的按鈕的正確方法……

使用 React Router 的withRouter HOC 將這些 props 傳遞給你的組件:

  • 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

為什么不使用與按鈕相同的 css 來裝飾鏈接標簽。

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

如果您使用的是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>

您可以在此處閱讀更多內容。

react-router useHistory開始,您可以使用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 在他們的評論中所說的那樣訪問

但是這是不可訪問的,因為按鈕不是標簽,因此它沒有鏈接行為,例如在新頁面中打開鏈接。 它對於屏幕閱讀器也不是最佳選擇。

我使用路由器和 < Button/>。 沒有<鏈接/>

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

對於任何使用React 16.8+ (鈎子)和 React Router 5 尋找解決方案的人:

您可以使用帶有以下代碼的按鈕更改路線:

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

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

你不需要用高階組件“withRouter”包裝你的組件來訪問這些道具。

使用樣式組件可以輕松實現

首先設計一個樣式按鈕

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 版本 6 的更新:

這里的各種答案就像是 react-router 進化的時間線🙂

使用 react-router v6 的最新鈎子,現在可以通過useNavigate鈎子輕松完成。

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

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

許多解決方案都專注於使事情復雜化。

使用 withRouter 是一個非常長的解決方案,對於像鏈接到應用程序中其他地方的按鈕這樣簡單的東西。

如果您要使用 SPA(單頁應用程序),我找到的最簡單的答案是與按鈕的等效類名一起使用。

這可確保您保持共享狀態/上下文,而無需像之前那樣重新加載整個應用程序

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>

使用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>

我建議您在Link組件上使用component屬性。 使用它,您可以有效地將任何組件從 React Rotuer 的角度視為a組件。 例如,您可以創建自己的“按鈕”組件,然后使用它。


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

<Link to="/somewhere" component={MyButton}>Potentially pass in text here</Link>
<Button component={Link} to="/dashboard" type="button">
    Click Me!
</Button>

當我搜索答案時,每個人都在談論舊版本的 react-router-dom,因此對於那些想要在功能組件中使用鈎子的人來說,這可能是有用的答案。 由於在新版本中很少更改掛鈎,甚至 withRouter 也不適用,您需要制作自定義 HOC。

我們可以通過功能組件來實現,您可以使用您的按鈕,然后通過 useNavigate 鈎子描述 onClick 事件觸發到下一頁。

React-Router-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高階組件以注入“路由道具”,就像react-router-dom v5.x 中的withRouter HOC 所做的那樣。


這只是一個普遍的想法。 如果你想使用Navigate 這里有一個例子custom 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);

這將為類組件注入一個props

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

例如:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM