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

React组件无法访问props问题:点击按钮触发TypeError报错求助

React组件中访问props报错的解决方案

错误原因

点击按钮触发action函数时,this.props.text抛出Cannot read properties of undefined (reading 'text')错误,核心问题是普通函数作为事件回调时,this指向发生了改变:这里的action是普通函数,当它作为按钮的点击事件监听器执行时,this指向的是触发事件的<button>元素,而非React组件实例,自然无法访问组件的props。

三种可行解决方案

方案1:使用箭头函数定义回调

箭头函数会继承外层作用域的this(也就是组件实例),直接解决this指向问题:

import React from "react";

class Canvas extends React.Component {
  componentDidMount() {
    const canvas = this.refs.canvas;
    const button = this.refs.button;
    const ctx = canvas.getContext("2d");
    
    // 改用箭头函数
    const action = () => {
      console.log("HI")
      ctx.font = "40px Consolas";
      ctx.fillStyle = "#F5F5F5";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.fillStyle = "#000000";
      ctx.fillText(this.props.text, 10, 40);
      button.removeEventListener("click", action);
    }
    
    button.addEventListener("click", action);
  }

  render() {
    return (
      <div>
        <canvas ref="canvas" width={300} height={300} />
        <button ref="button" style={{
          display: "block",
          margin: "auto",
          marginTop: "10px"
        }}>Show</button>
      </div>
    );
  }
}
export default Canvas;

方案2:手动绑定this到回调函数

通过bind方法将组件实例的this绑定到action函数,注意要保存绑定后的函数引用,保证添加和移除监听器用的是同一个函数:

import React from "react";

class Canvas extends React.Component {
  componentDidMount() {
    const canvas = this.refs.canvas;
    const button = this.refs.button;
    const ctx = canvas.getContext("2d");
    
    function action() {
      console.log("HI")
      ctx.font = "40px Consolas";
      ctx.fillStyle = "#F5F5F5";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.fillStyle = "#000000";
      ctx.fillText(this.props.text, 10, 40);
      button.removeEventListener("click", boundAction);
    }
    
    // 绑定this并保存引用
    const boundAction = action.bind(this);
    button.addEventListener("click", boundAction);
  }

  render() {
    return (
      <div>
        <canvas ref="canvas" width={300} height={300} />
        <button ref="button" style={{
          display: "block",
          margin: "auto",
          marginTop: "10px"
        }}>Show</button>
      </div>
    );
  }
}
export default Canvas;

方案3:提前保存组件实例的引用

在componentDidMount里用变量保存this(比如that),然后在action函数中通过这个变量访问props:

import React from "react";

class Canvas extends React.Component {
  componentDidMount() {
    const canvas = this.refs.canvas;
    const button = this.refs.button;
    const ctx = canvas.getContext("2d");
    // 保存组件实例的引用
    const that = this;
    
    function action() {
      console.log("HI")
      ctx.font = "40px Consolas";
      ctx.fillStyle = "#F5F5F5";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.fillStyle = "#000000";
      // 使用that访问props
      ctx.fillText(that.props.text, 10, 40);
      button.removeEventListener("click", action);
    }
    
    button.addEventListener("click", action);
  }

  render() {
    return (
      <div>
        <canvas ref="canvas" width={300} height={300} />
        <button ref="button" style={{
          display: "block",
          margin: "auto",
          marginTop: "10px"
        }}>Show</button>
      </div>
    );
  }
}
export default Canvas;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 01:20:32