Wie übergebe ich Parameter mit React Router v6 an Link?
Dies ist meine Hauptabschnittsklasse, in der alle Routen zu den Links beibehalten werden
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>
)}}
Dies ist meine Kartenseite, auf der Daten aus dem Kontext abgerufen werden.
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
Von hier aus hatte ich die val.id mit LINK an die URL der Seite übergeben
<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>
)}}
Ich möchte auf die Link-URL auf der Detailseite meines Produkts zugreifen, die wie folgt lautet:
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> ))} </> ) }}
Leider wird ein Fehler angezeigt, der TypeError besagt: Die Eigenschaft 'params' von undefined kann nicht gelesen werden
Antworten
Probleme)
- React-Router-Dom v6-
RouteKomponenten, die über dieelementRequisite gerendert werden, erhalten keine Routen-Requisiten . - Route Kinder Komponenten müssen Gebrauch reagieren Haken Zugang die Strecke Kontext, dh
useParams,useLocation,useHistoryusw ... und damit funktionelle Komponenten sein müssen. - Es gibt keine
withRouterKomponente höherer Ordnung mehr.
Lösung
DetailsPage ist eine klassenbasierte Komponente. Ich sehe einige Optionen, um Zugriff auf die Übereinstimmungsparameter der Route zu erhalten.
- Konvertieren Sie
DetailsPagein eine funktionale Komponente und verwenden Sie denuseParamsReaktionshaken. - Schreiben Sie Ihr eigenes
withRouterHOC, um auf den Routenkontext zuzugreifen, und übergeben Sie als Requisiten einen der Werte, auf die Sie mit dem React-Hook zugreifen können.
Ich werde mich nicht mit der Konvertierung einer klassenbasierten Komponente in eine funktionale Komponente befassen, sondern kann eine einfache HOC-Lösung bereitstellen, die an die Übereinstimmungsparameter DetailsPage( oder eine andere klassenbasierte Komponente ) übergeben werden kann.
const withRouter = WrappedComponent => props => {
const params = useParams();
// etc... other react-router-dom v6 hooks
return (
<WrappedComponent
{...props}
params={params}
// etc...
/>
);
};
Sie können Ihre klassenbasierten Komponenten jetzt auf die sehr vertraute Weise wie in Version 4 / Version 5 verpacken und exportieren .
v6 api-referenz