You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js子组件通过props调用父组件函数报错及修复方法

问题描述

尝试通过子组件修改父组件状态,已在父组件创建handleDelete函数并尝试通过props传递给子组件Product,但项目运行时出现错误:TypeError: this.props.handleDelete is not a function。

相关代码

Products组件(父组件)

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;

Product组件(子组件)

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)

问题原因

  • props传递名称不匹配:父组件给子组件传递的属性是onClick,但子组件中尝试调用的是this.props.handleDelete,名称不对应导致子组件无法获取到目标函数。
  • 按钮事件绑定错误:子组件中delete按钮使用onDelete={this.handleDelete()},直接执行了函数而非传递函数引用,会在组件渲染时立即触发handleDelete,此时因第一个问题导致函数不存在,直接抛出错误;同时HTML原生按钮没有onDelete事件,需使用标准的onClick。
  • format方法调用错误:子组件中format(this.count)里的this.count未定义,应使用this.state.count。

修复方案

1. 修正父组件(Products)

将传递给子组件的props名称从onClick改为handleDelete,确保名称匹配,并补充实际删除逻辑:

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) => (
                    {/* 修改props名称为handleDelete */}
                    <Product handleDelete={this.handleDelete} id={p.id} key={index} productName={p.productName} count={p.count} >
                        Lorem, ipsum dolor sit amet consectetur adipisicing elit.
                    </Product>
                ))}
            </>
        );
    }

    handleDelete = (productId) => {
        // 过滤掉对应id的产品,更新父组件状态
        this.setState(prevState => ({
            products: prevState.products.filter(product => product.id !== productId)
        }));
        console.log(productId);
    }

}

export default Products;

2. 修正子组件(Product)

  • 修正delete按钮的事件绑定,传递函数引用而非立即执行,同时改用标准onClick事件;
  • 修正format方法的调用参数,传入正确的this.state.count:
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>
        {/* 修正format的参数为this.state.count */}
        <span className="m-2 badge bg-primary">{this.format(this.state.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>
        {/* 改用onClick事件,传递函数引用而非立即执行 */}
        <button onClick={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(count) {
    if (count === 0) {
      return "zero";
    } else {
      return count;
    }
  }
}
export default Product;

内容的提问来源于stack exchange,提问作者hmahdavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:30:29