使用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属性。
正确的写法(结合你的需求)
首先记住两个关键点:
injectIntl直接作为compose的参数,不要加括号- 你的
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

