Wie übergebe ich Parameter mit React Router v6 an Link?

Nov 11 2020

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

1 DrewReese Nov 13 2020 at 07:20

Probleme)

  1. React-Router-Dom v6- RouteKomponenten, die über die elementRequisite gerendert werden, erhalten keine Routen-Requisiten .
  2. Route Kinder Komponenten müssen Gebrauch reagieren Haken Zugang die Strecke Kontext, dh useParams, useLocation, useHistoryusw ... und damit funktionelle Komponenten sein müssen.
  3. 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.

  1. Konvertieren Sie DetailsPagein eine funktionale Komponente und verwenden Sie den useParamsReaktionshaken.
  2. 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