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

React Redux类组件继承Redux连接组件时触发Super expression TypeError

错误根因定位

这个报错和新版React-Redux兼容性、循环依赖都没有关系,核心原因是你继承的父类根本不是合法的ES类构造函数。
你在引入AutocompleteWidget时,拿到的不是自己编写的那个继承自BaseWidget的原生类组件:

  • AutocompleteWidget模块中,export default导出的是connect(mapStateToProps, mapDispatchToProps)(AutocompleteWidget)的返回值
  • connect是高阶函数,返回的是经过Redux逻辑封装的React组件,这个返回值既不是ES类,也不是可被extends使用的构造器
  • 当你书写class AssetWidget extends 导入的AutocompleteWidget时,由于父类不是合法构造函数,直接触发TypeError: Super expression must either be null or a function
适配方案(无需重写原有组件)

按照你不改动原有组件核心逻辑的要求,仅需调整AutocompleteWidget的导出结构,将原生类单独暴露供后续继承使用即可:

调整AutocompleteWidget的导出逻辑

将内部原生类做命名导出,保留原有默认导出逻辑完全不变,不影响已有的业务页面使用:

import { getAutocompleteOptions } from 'options/modules/autocomplete';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import BaseWidget from './BaseWidget';

// 原生类组件,单独命名导出供后续业务组件继承
export class RawAutocompleteWidget extends BaseWidget {
  onChange = e => {
    this.props.onChange({ target: { value: e } });
  };

  get options() {
    return ['options0', 'options1', 'options2'];
  }
}

const mapStateToProps = ({ autocomplete }) => {
  return {
    autocomplete,
  };
};

const mapDispatchToProps = dispatch =>
  bindActionCreators(
    {
      getAutocompleteOptions,
    },
    dispatch,
  );

// 原有默认导出逻辑保留,供页面直接引入使用
export default connect(mapStateToProps, mapDispatchToProps)(RawAutocompleteWidget);

调整AssetWidget的导入逻辑

AssetWidget继承时,导入的是未被connect包裹的原生类,而非模块默认导出的包装组件:

// 导入命名导出的原生类,而非默认导出的connect包装版本
import { RawAutocompleteWidget } from './AutocompleteWidget';

export default class AssetWidget extends RawAutocompleteWidget {
  get options() {
    return ['asset0', 'asset1', 'asset2'];
  }
}

如果AssetWidget本身需要连接Redux获取数据,单独给AssetWidget套connect逻辑即可,和原有组件的逻辑完全解耦。

类组件迁移的注意事项
  • ES类的extends语法要求父类必须是合法的构造函数,普通对象、高阶组件、undefined作为父类都会触发当前报错
  • 不要试图继承connect返回的包装组件:这个包装组件的核心作用是透传store注入的props,本身不会继承内部原组件的原型方法(比如你重写的get options、onChange),就算不触发报错,继承得到的逻辑也完全错误
  • 类组件的继承链上,所有被继承的类必须是原生可实例化的类,任何经过高阶组件包装的组件,都需要剥离出内部的原生类再做继承

内容的提问来源于stack exchange,提问作者Kyle Calica-St

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 15:15:07