Jak przekazać parametry do łącza za pomocą routera React v6?

Nov 11 2020

To jest moja główna klasa sekcji, w której przechowywane są wszystkie trasy do linków

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>
        )}}

To jest moja strona karty, która pobiera dane z kontekstu.

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

Stąd przekazałem val.id do adresu URL strony za pomocą 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>
  )}}

Chcę uzyskać dostęp do adresu URL linku do strony szczegółów mojego produktu, która jest następująca:

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>  ))} </> )  }}

Niestety wyświetla błąd informujący o błędzie TypeError: Cannot read property „params” of undefined

Odpowiedzi

1 DrewReese Nov 13 2020 at 07:20

Zagadnienia)

  1. RouteKomponenty react-router-dom v6 renderowane przez właściwość elementnie otrzymują właściwości trasy .
  2. Trasa dzieci komponenty muszą użycie reagować haki dostępu kontekst trasy, czyli useParams, useLocation, useHistory, etc ... i dlatego muszą być elementy funkcjonalne.
  3. Nie istnieje już withRouterkomponent wyższego rzędu.

Rozwiązanie

DetailsPage jest komponentem klasowym. Czy widzę kilka opcji uzyskiwania dostępu do parametrów dopasowania trasy.

  1. Przekształć DetailsPagew element funkcjonalny i użyj useParamszaczepu reagowania.
  2. Napisz swój własny withRouterHOC, aby uzyskać dostęp do kontekstu trasy i przekaż jako właściwości dowolne z dostępnych wartości reagowania.

Nie będę omawiał konwertowania komponentu opartego na klasach na komponent funkcjonalny, ale mogę zapewnić proste rozwiązanie HOC do przekazania DetailsPage( lub dowolnego innego komponentu opartego na klasach ) parametrów dopasowania.

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

  return (
    <WrappedComponent
      {...props}
      params={params}
      // etc...
    />
  );
};

Możesz teraz opakowywać i eksportować komponenty oparte na klasach w bardzo znany sposób, w jakim były z wersji 4/5.

v6 api-reference