如何使用React路由器v6将参数传递到链接



这是我的主要部分类,链接的所有路由都保持

export default class Section extends React.Component {
render() {
return (
<div style={{backgroundColor:"white"}}>
<Routes>
<Route path="/"  element={<Home/>} />
<Route path="/discover" element={<Discover/>}   />
<Route path="/shop/makeup" element={<Makeup/>}  />
<Route path="/home/:id" element={<DetailsPage/>}  />
</Routes>
</div>
)}}

这是我的卡片页面,它正在从上下文中获取数据。

import React from 'react';
import {DataContext} from './CardData.js';
import {Link} from 'react-router-dom'
import '../App.css';
export default class HomeCard extends React.Component {
static contextType = DataContext;
render(){
const {products} = this.context;
return (
<div>
<div className="card">
{ products.map((val,index)=>{
return(
<div className="card" key={val.id}>
<Card style={{ width: '14rem' }}  className="cardhead">
<Card.Img variant="top" src={val.imgsrc} className="cardimg"/>
<Card.Body>
<Card.Text>{val.mname}
</Card.Text>
<Card

从这里开始,我使用链接将val.id传递到页面的url

<Link to={`/home/${val.id}`}>
<Button className="overlay" variant="primary">
{/* <a  style={{color:"white"}} href={props.link} className="card-link">View</a> */}
View</Button> </Link>
<Card.Text><strong>{val.price}</strong>
</Card.Text>
<Card.Text><strong>{val.id}</strong>
</Card.Text>
</Card.Footer>
</Card.Body>
</Card>
</div>);                
</div>
)}}

我想访问链接url到我的产品的详细信息页面,如下所示:

export default class DetailsPage extends React.Component {
static contextType = DataContext;
state = {
product: []
}
getProduct = () =>{
if(this.props.match.params.id){
const res = this.context.products;
const data = res.filter(item =>{
return item.id === this.props.match.params.id
})
this.setState({product: data})
}};
componentDidMount(){
this.getProduct();
}
render() {
const {product} = this.state;
const {addCart} = this.context;
return (
<>
{product.map(item =>(
<div className="details" key={item.id}>
<img src={item.imgsrc} alt=""/>
<div className="box">
<div className="row">
<h2>{item.mname}</h2>
<span>${item.price}</span>
</div>
<Link to="/cart" className="cart" onClick={() => addCart(item.id)}>
Add to cart
</Link>
</div>   </div>  ))} </> )  }}

不幸的是,它给出了一个错误,称TypeError:无法读取未定义的属性"params">

使用react路由器dom v6

父组件(应用程序(

<Route path="/something/:id" element={<Something />} />

子组件(Something(

import { useParams } from "react-router-dom";
const Something = (props) => {
let { id } = useParams(); 
useEffect(() => {
console.log(`/something/${id}`);
},[]);
// .....
}

问题

  1. react router通过element道具渲染的dom v6Route组件不接收路由道具
  2. 路由子组件必须使用react hook访问路由上下文,即useParamsuseLocationuseNavigate等,因此必须是功能组件
  3. 不再存在withRouter高阶组件

解决方案

DetailsPage是一个基于类的组件,所以我看到了几个访问路由匹配参数的选项。

  1. DetailsPage转换为函数组件,并使用useParamsreact钩子
  2. 编写自己的withRouterHOC来访问路由上下文,并将任何react钩子可访问的值作为道具传递

我不涉及将基于类的组件转换为函数组件,但可以提供一个简单的HOC解决方案,将匹配参数传递给DetailsPage(或任何其他基于类的构件(。

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

你现在可以包装&以非常熟悉的方式导出基于类的组件,它们来自v4/v5。

通过React Router v6中的Link组件,通过类似<Link to="/" state={{ foo: bar }}>的名为state的单独道具传递道具。

示例:

<Link
to={`/login`}
state={{ from: "the-page-id" }}
>
Login to see this page
</Link>

并使用useLocation()钩子检索:

import { useLocation } from "react-router-dom";
...
const location = useLocation();
const { from } = location.state;
console.log(from); // output: "the-page-id"

这应该只用于函数组件,而不是类组件。

我遇到了同样的问题,并在互联网上搜索了一个简单的解决方案。我不想把我所有的类组件都重写为函数组件,但我认为我可能必须这样做。然而,我使用了一个带有useParams((的withRouter函数,它运行得很好,很容易理解。

要解决您的问题,这样您就不必将DetailsPage类重写为函数,请执行以下步骤:

  1. 在类的开头添加以下代码行:

    import { useParams } from 'react-router-dom';
    
  2. 然后在你的类上面添加这个函数(准确地复制它(:

    export function withRouter(Children){
    return(props)=>{
    const match  = {params: useParams()};
    return <Children {...props}  match = {match}/>
    }
    }
    
  3. 接下来,将类定义更改为:

    class DetailsPage extends React.Component {
    
  4. 在课程末尾添加以下代码行:

    export default withRouter(DetailsPage);
    

以编程方式导航

useNavigate发送参数

const navigate = useNavigate();
function _navigateToPage (pageNumber) {
const page = pageNumber
const title = "Hello World";
navigate("/fragment", {
state:{
page,
title
},
});
}

使用useLocation检索其他页面中的参数

const params = useLocation();
console.log(params);

最新更新