Search code examples
javascriptreactjse-commerce

How to pass data between sibling components React?


I am working on a React eCommerce website and I am having difficulties in showing the pdp (product detail page). The process should be that whenever a user clicks on a <Picture Card /> component, then it should open up the pdp of that product. Right now, if this happens I managed to log out the name and id of each product, but I cannot make it appear on the pdp page (I dont know how to pass the data here).

My question is, how can I pass the data from <Shop /> component to <Pdp /> component ?

Thank you very much in advance! Hope someone can help me

My code structure:

App.js
   ├── Header.js
   ├── Home.js
   ├── shop.js
            ├── PictureCard.js
   ├── Pdp.js
   ├── About.js
   └── Footer.js

My code:

Main.js

import React from 'react'
import { Switch, Route } from 'react-router-dom'

import Home from './Home'
import Shop from './Shop'
import About from './About'
import Pdp from './Pdp'

function Main() {
    return (
        <Switch> {/* The Switch decides which component to show based on the current URL.*/}
            <Route exact path='/' component={Home}></Route>
            <Route exact path='/shop' component={Shop}></Route>
            <Route exact path='/pdp' component={Pdp}></Route>
            <Route exact path='/about' component={About}></Route>
        </Switch>
    )
}

export default Main

Shop.js

import React from "react"
import PictureCard from "./PictureCard"

import profile2 from "../images/profile2.jpg"

import './Shop.css'

class Shop extends React.Component {
     constructor() {
          super()
     }

     handleClick(id, name) {
          console.log(id, name)
     }

     render() {
          return (
               <div className="shop-container">
                   <h3 className="filter-title">All pictures/</h3>
          
                   <div className="shop-grid">
                       <PictureCard
                            id="1"
                            image={profile2}
                            title="Strandhill Cannon Susnet"
                            price="20"
                            handleClick={this.handleClick}
                       />
                       <PictureCard
                            id="2"
                            image={profile2}
                            title="Bundoran in Winter"
                            price="20"
                            handleClick={this.handleClick}
                       />
                       <PictureCard
                            id="3"
                            image={profile2}
                            title="Mullaghmore Runner"
                            price="20"
                            handleClick={this.handleClick}
                       />
                   </div>
               </div>
           )
     }
}

export default Shop;

PictureCard.js

import React from "react"

import "./PictureCard.css"

import { Link } from "react-router-dom"

class PictureCard extends React.Component {
    constructor() {
        super()
    }

    render() {
        return(
            <div className="picure-card-container" onClick={() => this.props.handleClick(this.props.id, this.props.title)}>
                <Link to="/pdp" className="no-dec">
                    <img src={this.props.image} className="picture-card-image"></img>
                    <h6 className="picture-card-title">{this.props.title}</h6>
                    <p className="picture-card-price">€ {this.props.price}</p>
                </Link>
            </div>
        )
    }
}

export default PictureCard

Pdp.js

import React from "react"

import profile2 from "../images/profile2.jpg"

import './Pdp.css'

class Pdp extends React.Component {
     constructor() {
          super()
     }
     

     render() {
          return (
               <div className="pdp-page">
                   <h3 className="filter-title">All pictures/{this.props.title}</h3>
                   <div className="pdp-container">
                       <div>
                            Hello
                       </div>
                   </div>
               </div>
           )
     }
}

export default Pdp;

Solution

  • You can create dynamic routes for pdp page like so

    <Route path="/pdp/:productId" component={Pdp}/>
    

    Then in the PictureCard component, create links like

    <Link to=`/pdp/${this.props.id}`>
    

    Inside the pdp component, you should get ids like this.props.match.params.productId.

    Then using this id, you can call your API to get all the product details to be shown in the page.