代码之家  ›  专栏  ›  技术社区  ›  hmahdavi

如何通过Reac.js中的子组件和道具来调用父组件函数?

  •  1
  • hmahdavi  · 技术社区  · 11 月前

    我想用子组件更改父组件的状态。

    我在父组件中创建一个函数,并通过props将其传递给子组件。

    产品组件代码:

    import React, { Component } from 'react';
    import Product from './product';
    
    class Products extends Component {
        state = {
            products: [
                { id: 1, count: 2, productName: 'laptp' },
                { id: 2, count: 1, productName: 'phone' },
                { id: 3, count: 4, productName: 'airpods' }
            ]
        }
        render() {
            return (
                <>
                    {this.state.products.map((p, index) => (
                        <Product onClick={this.handleDelete} id={p.id} key={index} productName={p.productName} count={p.count} >
                            Lorem, ipsum dolor sit amet consectetur adipisicing elit.
                        </Product>
                    ))}
                </>
            );
        }
    
        handleDelete = (productId) => {
            console.log(productId);
        }
    
    }
    
    export default Products;
    

    产品组件代码:

    import { Component } from "react";
    
    
    class Product extends Component {
      state = {
        count: this.props.count,
        productName: this.props.productName
      }
      render() {
        return (
          <div>
            <span className="m-2 text-info"> {this.props.productName}</span>
            <span className="m-2 badge bg-primary">{this.format(this.count)}</span>
            <button onClick={this.handleIncrement} className="m-2 btn btn-sm btn-success">+</button>
            <button onClick={this.handleDecrement} className="m-2 btn btn-sm btn-warning">-</button>
            <button onDelete={this.handleDelete()} className="m-2 btn btn-sm btn-danger">delete</button>
            <p>{this.props.children}</p>
          </div>
        );
      }
      handleIncrement = () => {
        const { count } = this.state;
        this.setState({ count: count + 1 });
      }
      handleDecrement = () => {
        const { count } = this.state;
        this.setState({ count: count - 1 });
      }
      handleDelete = () => {
        this.props.handleDelete(this.props.id)
      }
      format() {
        if (this.state.count === 0) {
          return "zero";
        } else {
          return this.state.count;
        }
      }
    }
    export default Product;
    

    index.js代码:

    import Products from "./components/products";
    import ReactDOM from "react-dom";
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(<Products />);
    

    当我开始项目时,得到错误:

    我有什么问题?我该怎么修?

    this.props.handleDelete is not a function
    TypeError: this.props.handleDelete is not a function
        at Product.handleDelete (http://localhost:3000/main.a60ab9ca1348fe27abe1.hot-update.js:47:18)
        at Product.render (http://localhost:3000/main.a60ab9ca1348fe27abe1.hot-update.js:83:23)
        at finishClassComponent (http://localhost:3000/static/js/bundle.js:23142:35)
        at updateClassComponent (http://localhost:3000/static/js/bundle.js:23099:28)
        at beginWork (http://localhost:3000/static/js/bundle.js:24725:20)
        at beginWork$1 (http://localhost:3000/static/js/bundle.js:29665:18)
        at performUnitOfWork (http://localhost:3000/static/js/bundle.js:28935:16)
        at workLoopSync (http://localhost:3000/static/js/bundle.js:28858:9)
        at renderRootSync (http://localhost:3000/static/js/bundle.js:28831:11)
        at recoverFromConcurrentError (http://localhost:3000/static/js/bundle.js:28323:24)
    
    1 回复  |  直到 11 月前
        1
  •  1
  •   Ikram Akbar    11 月前

    在您的 Products 组件,您正在通过 handleDelete 用作名为的道具 onClick :

    <Product onClick={this.handleDelete} ... />
    

    但在你的 Product 组件,您正试图将其作为 手柄删除 :

    this.props.handleDelete(this.props.id)
    

    要解决此问题,您需要确保道具名称匹配。您可以在中更改道具名称 产品 组件到 手柄删除 :

    <Product handleDelete={this.handleDelete} ... />
    

    现在 this.props.handleDelete 在中 产品 组件应正确参考 手柄删除 中的函数 产品 组成部分

    此外,在您的 产品 组件,您正在调用 手柄删除 由于括号的原因,在呈现按钮时立即 () :

    <button onDelete={this.handleDelete()} ... />
    

    您应该传递函数引用:

    <button onDelete={this.handleDelete} ... />
    

    然而 onDelete 不是按钮的有效事件处理程序。你应该使用 单击 相反:

    <button onClick={this.handleDelete} ... />
    

    有了这些更改,您的代码应该可以按预期工作。