Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
241 views
in Technique[技术] by (71.8m points)

javascript - How to pass data from child to parent component in React.JS?

I am working on a React eCommerce website and I am having difficulties in showing the pdp complete with all the fields I need (title(ok), price(NO), description(NO), image(NO)). 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 show in the page the title trough React Routes, and I can log out all the fields I need correctly, but I cannot make it appear on the pdp page (I dont know how to pass the data here).

I was thinking to lift up the state to my Parent component (<App /> ) and then pass it to my <Pdp /> component as props. But how can I do this exactly ?

Right now I get the folowing error when I click on a <Picture Card /> component: "TypeError: this.props.parentCallback is not a function"

What am I missing ? Thanks in advance!

My code structure:

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

My code:

App.js

import React from "react"
import Header from "./components/Header"
import Main from "./components/Main"
import Footer from "./components/Footer"

import './App.css';

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      data: null
    }
  }

  handleCallback = (childData) => {
    this.setState({
      data: childData
    })
  }

  render() {
    return (
      <div className="App">
          <Header />
          <Main parentCallback = {this.handleCallback}/>
          <Footer />
      </div>
    )
  }
  
}

export default App

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 path='/pdp/:productTitle' 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 { Link } from "react-router-dom"

import './Shop.css'

class Shop extends React.Component {

     constructor() {
          super()
          this.state = {
               productId: "",
               productTitle: "",
               productPrice: "",
               productDescription: "",
               productImage: ""
          }
          this.handleClick = this.handleClick.bind(this)
     }

     handleClick(id, name, price, description, image) {
          console.log(id, name, price, description, image)
          this.props.parentCallback("Data from child") //this is wrong ? why ?
          //getting the error TypeError: this.props.parentCallback is not a function

          
          /* this.setState({
               productId: id,
               productTitle: name,
               productPrice: price,
               productDescription: description,
               productImage: image
          }) */
     }
     

     render() {
          return (
               <div className="shop-container">
                   <h3 className="filter-title"><Link to="/shop" className="no-dec">All pictures</Link></h3>
                   
                
                   <div className="shop-grid">
                       <PictureCard
                            id="1"
                            image={profile2}
                            title="Strandhill Cannon Susnet"
                            price="20"
                            description="Colourful sunset at the cannon of Strandhill during lockdown"
                            handleClick={this.handleClick}
                       />
                       <PictureCard
                            id="2"
                            image={profile2}
                            title="Bundoran in Winter"
                            price="20"
                            description="Snowy mountains view behind Bundoran colourful houses"
                            handleClick={this.handleClick}
                       />
                       <PictureCard
                            id="3"
                            image={profile2}
                            title="Mullaghmore Runner"
                            price="20"
                            description="Being active during lockdown in County Sligo"
                            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, this.props.price, this.props.description, this.props.image)}>
                <Link to = {`/pdp/${this.props.title}`} 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 { Link } from "react-router-dom"

import './Pdp.css'

class Pdp extends React.Component {
     constructor() {
          super()
     }
     
     render() {
          return (
               <div className="pdp-page">
                   <h3 className="filter-title">
                        <Link to="/shop" className="no-dec">All pictures</Link> <span>&#8250;</span> <a href="" className="no-dec">{this.props.match.params.productTitle}</a>
                    </h3>
                   <div className="pdp-container">
                       <div>
                            <img src={this.props.image} className="pdp-image"></img>
                       </div>
                       <div className="pdp-info-container">
                            <h3 className="pdp-title">{this.props.match.params.productTitle}</h3>
                            <p className="pdp-info-paragraph">€ price {this.props.price}</p>
                            <p className="pdp-info-paragraph">description {this.props.description}</p>
                            <button className="purchase-button">Purchase</button>
                       </div>
                   </div>
               </div>
           )
     }
}

export default Pdp;


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Try this

        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({parentCallback}) {
            return (
                <Switch> {/* The Switch decides which component to show based on the current URL.*/}

 //Please try this thing hope it will works
                    <Route exact path='/'  
         render={(props)=>
    (<Home parentCallback={parentCallback} 
    {...props}/>
         )}/>


 <Route  exact path='/shop'  
         render={(props)=>
    (<Shop parentCallback={parentCallback} 
    {...props}/>
         )}/>

    <Route  path='/pdp/:productTitle'
         render={(props)=>
    9<Pdp parentCallback={parentCallback} 
    {...props}/>
         )}/>

 <Route exact path='/about'
         render={(props)=>
    (<About parentCallback={parentCallback} 
    {...props}/>
         )}/>
                </Switch>
            )
        }
        
        export default Main

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...