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

React类组件箭头函数中JSX使用this.DemoRenderer报错问题咨询

React 16.8.6类组件中JSX引用实例方法组件的异常问题

在React 16.8.6版本的类组件中,用箭头函数定义的customerRender方法里,console.log能正常输出this.DemoRenderer函数,但返回<this.DemoRenderer />时会抛出错误:React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined。将该方法改为普通函数并在constructor中绑定this后,报错消失,但相同代码在在线编辑器中运行无报错,以下是问题原因分析:

错误代码示例

import React, {Component} from "react";
import ReactDOM from "react-dom";

class App extends Component {
  constructor(props) {
    super(props);
    this.DemoRenderer = function () {
      return <div>DemoRenderer</div>;
    };
  }
  customerRender = () => {
     // 此处能正常打印this.DemoRenderer函数
     console.log(this.DemoRenderer);

    // 但返回下方JSX会报错:
    // React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined
    return <this.DemoRenderer />;
  };
  render() {
    return (
      <div>
        hello
        {this.customerRender()}
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

无错误代码示例

class App extends Component {
  constructor(props) {
    super(props);
    this.DemoRenderer = function () {
      return <div>DemoRenderer</div>;
    };
    // 绑定this到customerRender
    this.customerRender = this.customerRender.bind(this);
  }
  customerRender() {
    return <this.DemoRenderer />;
  };
  // ... 其余render方法同上
}

项目依赖配置

"dependencies": {
    "react": "16.8.6",
    "react-dom": "16.8.6",
    "react-scripts": "3.0.1"
  },
  "devDependencies": {
    "typescript": "3.3.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },

问题原因分析

  1. JSX编译阶段的this指向差异
    JSX会被Babel编译为React.createElement调用,对于<this.DemoRenderer />这种写法,编译时会优先解析this的上下文。箭头函数作为类字段(customerRender = () => {})的初始化顺序在constructor之后,但旧版本Babel编译类内部JSX时,会将this.DemoRenderer错误解析为类的静态属性而非实例属性——因为箭头函数类字段的作用域处理逻辑和普通类方法不同,导致编译阶段无法识别实例上的DemoRenderer,运行时自然返回undefined。

而普通类方法在constructor中绑定this后,作为原型方法,其内部JSX编译时会保留对实例this的引用,运行时能正确访问到实例上的DemoRenderer函数。

  1. 本地与在线环境的编译配置差异
    在线编辑器使用的Babel版本或配置更完善,对类字段和JSX的作用域处理做了优化,能够正确识别实例属性,因此相同代码不会报错。而本地环境使用的react-scripts 3.0.1对应的Babel版本较旧,存在这个编译逻辑的缺陷。

  2. 临时解决方案验证
    如果把this.DemoRenderer赋值给箭头函数内部的局部变量,再用变量作为组件,就能绕过编译阶段的错误解析:

customerRender = () => {
  const Renderer = this.DemoRenderer;
  return <Renderer />;
};

这种写法让JSX编译时直接引用局部变量,跳过对this的静态解析,运行时就能正确获取到实例方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:06:19