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

使用compose组合Material-UI与react-intl的HOC时报错求助

嘿,我来帮你搞定这个HOC组合的坑!你遇到的两个报错都是因为对compose和injectIntl的用法理解有偏差,咱们一步步拆解:

先分析两种写法的错误原因

第一种写法的问题

export default compose(
  withStyles(styles),
  withWidth(),
)(injectIntl(NavBar));

报错TypeError: Cannot call a class as a function的核心原因是:compose返回的函数只接收原始组件,但你提前用injectIntl(NavBar)把组件包装了一遍,相当于把一个已经被HOC转换过的组件丢给了compose的结果。compose内部会依次调用传入的HOC,每个HOC都需要接收未被包装的组件,你这操作相当于把类组件当成普通函数来调用,自然触发报错。

第二种写法的问题

export default compose(
  withStyles(styles),
  withWidth(),
  injectIntl(),
)(NavBar);

报错TypeError: Cannot read property 'displayName' of undefined是因为**injectIntl不需要加括号调用**!它本身就是一个接收组件作为参数的HOC函数,你加了()之后,相当于执行了injectIntl但没传组件,返回的不是合法的HOC,compose在处理这个无效HOC时,自然找不到displayName属性。

正确的写法(结合你的需求)

首先记住两个关键点:

  1. injectIntl直接作为compose的参数,不要加括号
  2. 你的styles是传给withWidth的配置项,不是withStyles的参数(你提到传给withStyles会报错)

用compose的正确姿势如下:

// 确保你引入了compose(比如redux或recompose的compose)
import { compose } from 'redux';

export default compose(
  // 顺序注意:compose是从右到左执行的,所以如果injectIntl需要先处理,放在最右边
  injectIntl,
  withWidth({ styles }), // 把styles传给withWidth的配置对象
  withStyles(/* 如果需要给withStyles传样式就写这里,不需要可以留空或去掉该HOC */)
)(NavBar);

关于你临时写法的说明

你临时用的export default withStyles(withWidth(styles))(injectIntl(NavBar))其实是个“歪打正着”的写法——withWidth(styles)返回的是一个HOC,而withStyles本来应该接收样式对象,这里相当于把HOC当成了样式传入,虽然能跑但不符合API规范,还是用上面的compose写法更规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:12:31