父状态->子组件->带有onClick的渲染组件不起作用

时间:2020-03-19 16:48:19

标签: javascript reactjs

组件流-

App.js -保持应用程序状态,呈现商店组件,将addToCart()函数和产品[[from state]]传递到Shop.js

Shop.js -映射产品并呈现带有附加到每个元素上的click事件的产品组件

问题- 我的 addToCart()函数不起作用。我在 addToCart()中只是一个简单的 console.log()进行测试。使其正常工作的唯一方法是将click事件附加到 map()函数之外的任何元素。有人可以告诉我我在做什么吗?错误吗?

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;

1 个答案:

答案 0 :(得分:0)

检查传递给产品组件的方法。它必须绑定在dom-元素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>