如何使用没有 <Link> 标签的 react-router-dom 发送参数
Posted
技术标签:
【中文标题】如何使用没有 <Link> 标签的 react-router-dom 发送参数【英文标题】:How to send params using react-router-dom without a <Link> tag 【发布时间】:2021-10-24 03:30:12 【问题描述】:我正在使用 react-router-dom v^6.0.0-beta.1 和 React v^17.0.1,我通过点击卡片列表中的卡片从一页导航到另一页:
PlayersPage.tsx
/** @jsxImportSource @emotion/react */
import React, useState, useEffect from 'react';
import Page from './Page';
import PageTitle from './PageTitle';
import Button, Card from 'react-bootstrap';
import css from '@emotion/react';
import pic from '../assets/samurai.png';
import useNavigate from 'react-router';
import Link from 'react-router-dom';
function PlayersPage()
interface PlayersDataType
id: number;
handle: string;
role: string;
avatar: string;
specialAbilities:
playerId: number;
authority: number;
charismaticLeadership: number;
combatSense: number;
credibility: number;
family: number;
interface: number;
juryRig: number;
medicalTech: number;
resources: number;
streedeal: number;
;
stats:
playerId: number;
int: number;
ref: number;
tech: number;
cool: number;
attr: number;
luck: number;
ma: number;
body: number;
emp: number;
run: number;
leap: number;
lift: number;
;
//const [isLoading, setIsLoading] = useState<boolean>(false);
const [playersData, setPlayersData] = useState<Array<PlayersDataType>>([]);
const navigate = useNavigate();
const createNew = () =>
navigate('../Create');
;
const handleSelect = () =>
navigate('../Player');
;
//Fetch all players from database
useEffect(() =>
//setIsLoading(true);
fetch('https://localhost:44326/api/Players/all')
.then((response) =>
if (response.ok)
return response.json();
)
.then((data) => setPlayersData(data));
//.then(setIsLoading(false));
, []);
return (
<Page>
<div>
<PageTitle>Toons</PageTitle>
<div
css=css`
justify-content: center;
margin-left: 255px;
margin-bottom: 10px;
`
>
<button onClick=createNew>Create New</button>
</div>
</div>
<div //Every card is listed in 1 column
css=css`
flex-direction: column;
margin-left: 40px;
`
>
playersData.map((data) => (
<div key=data.id>
<Card
css=css`
display: flex;
width: 500px;
height: 200px;
flex-direction: column;
//border: 2px solid black;
box-shadow: 0 3px 7px 0 rgba(30, 38, 46, 0.21);
cursor: pointer;
:hover
transform: scale(
1.2
); /* (150% zoom - Note: if the zoom is too large, it will go outside of the viewport) */
`
onClick=handleSelect
>
<div
css=css`
display: flex;
flex-direction: row;
//border: 2px solid orange;
`
>
<Card.Img
src=pic
css=css`
margin: 5px 10px 10px 10px;
width: 150px;
height: 150px;
border-radius: 50%;
box-shadow: 0 3px 7px 0 rgba(30, 38, 46, 0.21);
//border: 2px solid black;
`
/>
<Card.Body
css=css`
flex: 1;
flex-direction: row;
//border: 2px solid purple;
`
>
<div
css=css`
display: flex;
flex-direction: row;
//justify-content: space-between;
flex-wrap: wrap;
`
>
<Card.Text>Int:</Card.Text>
<Card.Text>data.stats.int</Card.Text>
<Card.Text>Ref:</Card.Text>
<Card.Text>data.stats.ref</Card.Text>
<Card.Text>Tech:</Card.Text>
<Card.Text>data.stats.tech</Card.Text>
<Card.Text>Cool:</Card.Text>
<Card.Text>data.stats.cool</Card.Text>
<Card.Text>Attr:</Card.Text>
<Card.Text>data.stats.attr</Card.Text>
<Card.Text>Luck:</Card.Text>
<Card.Text>data.stats.luck</Card.Text>
<Card.Text>Ma:</Card.Text>
<Card.Text>data.stats.ma</Card.Text>
<Card.Text>Body:</Card.Text>
<Card.Text>data.stats.body</Card.Text>
<Card.Text>Emp:</Card.Text>
<Card.Text>data.stats.emp</Card.Text>
<Card.Text>Run:</Card.Text>
<Card.Text>data.stats.run</Card.Text>
<Card.Text>Leap:</Card.Text>
<Card.Text>data.stats.leap</Card.Text>
<Card.Text>Lift:</Card.Text>
<Card.Text>data.stats.lift</Card.Text>
</div>
</Card.Body>
</div>
<Card.Title
css=css`
display: flex;
width: 150px;
flex-direction: row;
justify-content: center;
font-weight: bold;
margin-bottom: 10px;
`
>
data.handle, data.role
</Card.Title>
</Card>
<br></br>
</div>
))
</div>
</Page>
);
export default PlayersPage;
我想发送用户点击的任何卡片的data.id
。
有什么方法可以使用 onClick 函数在此处发送 data.id
作为参数:
<div key=data.id>
<Card
css=css`
display: flex;
width: 500px;
height: 200px;
flex-direction: column;
//border: 2px solid black;
box-shadow: 0 3px 7px 0 rgba(30, 38, 46, 0.21);
cursor: pointer;
:hover
transform: scale(
1.2
); /* (150% zoom - Note: if the zoom is too large, it will go outside of the viewport) */
`
onClick=handleSelect
>
并以某种方式将其发送到这里:
const handleSelect = () =>
navigate('../Player');
;
然后在另一个页面上使用该 id?
编辑:
这就是我现在正在尝试的:
onClick=() => handleSelect(data.id)
我认为这是正确的。然后在handleSelect函数中:
const handleSelect = (id: number) =>
history.push(pathname: '/Player',
state:
id: id,
,)
但是我在这方面遇到 3 个错误:Property 'push' does not exist on type 'History'.ts(2339)
和 Cannot find name 'pathname'.ts(2304)
以及 state
的相同错误。
编辑 2:
我添加了 const history = useHistory();
,并更新了handleSelect函数如下:
const handleSelect = (id: number) =>
history.push(
pathname: '/Player',
state:
id: id,
,
);
;
除了打字稿错误Module '"react-router-dom"' has no exported member 'useHistory'.ts(2305)
之外,一切似乎都很好。
【问题讨论】:
你可以使用 useHistory 钩子。检查这个:enter link description here 【参考方案1】:使用这个:
onClick=()=>handleSelect(data.id)
并修改您的handleSelect
如下:
const handleSelect = (id) =>
this.props.router.push(
pathname: '/pathname',
state:
id: id
)
;
或使用useHistory
:
const handleSelect = (id) =>
history.push(pathname: '/YOUR PATH',
state:
id: id,
,)
对于您的编辑部分:
-
导入 useHistory 并使用它:
import useHistory from "react-router-dom";
// in your component define a history variable
const history = useHistory();
// then use it whenever you want:
history.push(
pathname: '/your path', //change the value to whatever you want
state:
id: id, // you can add other variables as well
,
);
-
现在您可以在目标组件中访问此变量:
在类组件中:
this.props.location
在功能组件中:
import useLocation from 'react-router-dom';
const location = useLocation();
let id = location.state.id;
【讨论】:
在第一种方法中,我在 id:Parameter 'id' implicitly has an 'any' type.ts(7006)
上得到一个错误:'this' implicitly has type 'any' because it does not have a type annotation.ts(2683) PlayersPage.tsx(11, 10): An outer value of 'this' is shadowed by this container.
第一种方法是类组件!如果你使用功能组件,你应该使用useHistory
,你定义了useHistory吗?您应该按如下方式使用它:const history = useHistory();
用历史记录方法好了,我得到了这些错误:Property 'push' does not exist on type 'History'.ts(2339)
,Cannot find name 'pathname'.ts(2304)
,和Cannot find name 'state'.ts(2304)
。
我编辑了我的问题以显示我在哪里。
我收到错误:Module '"react-router-dom"' has no exported member 'useHistory'.ts(2305)
我已经运行了 yarn install 和 yarn add @types/react-router-dom 但问题仍然存在【参考方案2】:
在您的handleSelect
方法中,您需要传递data.id
参数。
onClick=handleSelect(data.id)
并在您的处理程序中处理它。但是你必须像这样包装函数。
const handleSelect = (clickEvent) => (dataId)
//dataId will be available to use here
navigate('../Player/');
;
然后我会看看 useHistory
钩子,因为历史道具被认为是遗留的。
import React from 'react';
import useHistory from 'react-router-dom';
const Hello = () =>
const history = useHistory();
const handleClick = () => history.push('/goodbye');
return (
<button type="button" onClick=handleClick>
Goodbye
</button>
);
;
export default Hello;
因此,当您推送到历史 URL 时,您可以创建使用该参数的路由。像这样的:
history.push('/yourURL/:dataId');
然后在该页面上,您可以拉下该参数,您的应用可以使用它。
【讨论】:
使用onClick=handleSelect(data.id)
不正确,应改为onClick=()=>handleSelect(data.id)
以上是关于如何使用没有 <Link> 标签的 react-router-dom 发送参数的主要内容,如果未能解决你的问题,请参考以下文章