问题
This is my main section class where all routes to the links is kept
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>
)}}
This is my card page which is getting data from the context.
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
From here i had passed the val.id to the url of the page using LINK
<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>
)}}
I want to access the the link url into the details page of my product which is as follows :
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> ))} </> ) }}
Unfortunately it is giving an error saying TypeError: Cannot read property 'params' of undefined
回答1:
Issue(s)
- react-router-dom v6
Route
components rendered via theelement
prop don't receive route props. - Route children components must use react hooks to access the route context, i.e.
useParams
,useLocation
,useHistory
, etc... and therefore must be functional components. - There no longer exists a
withRouter
Higher Order Component.
Solution
DetailsPage
is a class-based component do I see a couple options for getting access to the route's match params.
- Convert
DetailsPage
to be a functional component and use theuseParams
react hook. - Write your own
withRouter
HOC to access the route context and pass as props any of the react-hook accessible values.
I won't cover converting a class-based component to a functional component, but can provide a simple HOC solution to pass to DetailsPage
(or any other class-based component) the match params.
const withRouter = WrappedComponent => props => {
const params = useParams();
// etc... other react-router-dom v6 hooks
return (
<WrappedComponent
{...props}
params={params}
// etc...
/>
);
};
You can now wrap & export your class-based components in the very familiar way they were from v4/v5.
v6 api-reference
来源:https://stackoverflow.com/questions/64782949/how-to-pass-params-into-link-using-react-router-v6