简体   繁体   中英

Parent State -> Child Component -> Render Component with onClick not working

Component Flow -

App.js - holds state of application, renders shop component, passes down addToCart() function and products [[from state]] to Shop.js

Shop.js - Maps through products and renders a product component with a click event attached to each element

Problem - my addToCart() function is not working. I have just a simple console.log() inside of the addToCart() to test. The only way I can get it to work is if I attach the click event to any element outside of the map() function. Can someone please tell me what I am doing wrong?

App.js

import './App.css';
import { Route, Switch } from 'react-router-dom';
import Home from './components/Home';
import Shop from './components/Shop';
import News from './components/News';
import Contact from './components/Contact';
import Cart from './components/Cart';
import Profile from './components/Profile';
import Error from './components/Error';
import Nav from './components/Nav';

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            products : [
                {
                    id: 1,
                    productImage: 'someURL',
                    productName: 'outfit',
                    productPrice: 25
                },
                {
                    id: 2,
                    productImage: 'someURL',
                    productName: 'outfit',
                    productPrice: 25
                },
                {
                    id: 3,
                    productImage: 'someURL',
                    productName: 'outfit',
                    productPrice: 25
                }
            ],
            cartData : {
                items: [],
                total: 0
            },
            posts : [
                {
                    id: 1,
                    postImage : '',
                    postTitle : 'Post One',
                    postBody : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam, officiis. Sapiente ut culpa corporis repudiandae quis corrupti impedit a aperiam?'
                },
                {
                    id: 2,
                    postImage : '',
                    postTitle : 'Post Two',
                    postBody : 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Similique, perspiciatis.'
                },
                {
                    id: 3,
                    postImage : '',
                    postTitle : 'Post Three',
                    postBody : 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Repellendus incidunt saepe repudiandae asperiores corporis!'
                },
                {
                    id: 4,
                    postImage : '',
                    postTitle : 'Post Four',
                    postBody : 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Repellendus incidunt saepe repudiandae asperiores corporis!'
                },
                {
                    id: 5,
                    postImage : '',
                    postTitle : 'Post Five',
                    postBody : 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Repellendus incidunt saepe repudiandae asperiores corporis!'
                },
                {
                    id: 6,
                    postImage : '',
                    postTitle : 'Post Six',
                    postBody : 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Repellendus incidunt saepe repudiandae asperiores corporis!'
                }
            ]
        }
    }

    addToCart = () => {
        console.log("added");
    }

    removeFromCart = (productId) => {
        console.log("removed");
    }


    render() {
        return (
            <div className="App">
                <Nav></Nav>
                <Switch>
                    <Route path="/" component={Home} exact />
                    <Route path="/shop" render={() => <Shop addToCart={this.addToCart} removeFromCart={this.removeFromCart} products={this.state.products} /> } />
                    <Route path="/news" component={News} />
                    <Route path="/contact" component={Contact} />
                    <Route path="/cart" component={Cart} />
                    <Route path="/profile" component={Profile} />
                    <Route component={Error} />
                </Switch>
            </div>
        );
    }
}

export default App;

Shop.js

import React, { Component } from 'react';
import Product from './Product';

class Shop extends Component {
    render() {
        return (
            <div>
                <div className="shop-text">
                    <div className="custom-line"></div>
                    <h1>product catalog</h1>
                    <div className="custom-line"></div>
                </div>
                <div className="product-grid">
                    {this.props.products.map(product => {
                        return (
                            <Product onClick={this.props.addToCart} key={product.id} image={product.productImage} name={product.productName} price={product.productPrice}></Product>
                        )
                    })}
                </div>
            </div>
        )
    }
}

export default Shop;

Check the method pass to product component. It has to be bind on dom-element click(event).

 .product { border: 1px solid #d3d3d3; padding: 10px 50px; background: bisque; } .product-list { display: flex; justify-content: space-evenly; }
 <meta charset="UTF-8" /> <title>Hello World</title> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <!-- Don't use this in production: --> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <div id="root"></div> <script type="text/babel"> class App extends React.Component { onClick(product) { alert(JSON.stringify(product)) } render() { const products = [{name: "Milk"}, {name: "Shoes"}, {name: "Water"}] return <ShoppingCart products={products} addToCart={(product) => this.onClick(product)}/>; } } class ShoppingCart extends React.Component { render() { return ( <div className="product-list"> {this.props.products.map(x => ( <Product key={x.name } {...x} addToCart={this.props.addToCart} /> ))} </div> ); } } class Product extends React.Component { render() { return ( <div className="product"> <h1>{this.props.name}</h1> <button onClick={x => this.props.addToCart(this.props.name)}>add</button> </div> ); } } ReactDOM.render(<App />, document.getElementById("root")); </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM