这是我的主要部分类,链接的所有路由都保持
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}`);
},[]);
// .....
}
问题
- react router通过
element
道具渲染的dom v6Route
组件不接收路由道具 - 路由子组件必须使用react hook访问路由上下文,即
useParams
、useLocation
、useNavigate
等,因此必须是功能组件 - 不再存在
withRouter
高阶组件
解决方案
DetailsPage
是一个基于类的组件,所以我看到了几个访问路由匹配参数的选项。
- 将
DetailsPage
转换为函数组件,并使用useParams
react钩子 - 编写自己的
withRouter
HOC来访问路由上下文,并将任何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类重写为函数,请执行以下步骤:
-
在类的开头添加以下代码行:
import { useParams } from 'react-router-dom';
-
然后在你的类上面添加这个函数(准确地复制它(:
export function withRouter(Children){ return(props)=>{ const match = {params: useParams()}; return <Children {...props} match = {match}/> } }
-
接下来,将类定义更改为:
class DetailsPage extends React.Component {
-
在课程末尾添加以下代码行:
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);