实现HOC时触发TypeError: Object(…) is not a function求助
嘿,我帮你定位到问题根源了!你遇到的这个错误,核心原因是你把connect和HOC的组合顺序搞反了,导致最终导出的不是一个能正常包裹组件的高阶函数。
问题出在哪?
你当前的HOC导出代码是这样的:
export default connect(mapStateToProps)(withResults);
connect(mapStateToProps)会返回一个函数,这个函数的作用是接收一个React组件,然后返回和Redux store连接后的组件。但你现在把withResults(一个HOC函数,不是React组件)传给了它,这就导致connect无法正确处理,最终导出的结果不是一个可用的HOC,而是一个无效的对象/组件。当你在PrimaryResults里调用WithResults(PrimaryResults)时,本质上是在调用一个非函数的东西,自然会抛出TypeError。
两种修复方案
方案一:把connect整合到HOC内部
这是最直观的写法,让withResults本身负责把组件和Redux store连接起来:
import React from "react"; import { connect } from "react-redux"; const withResults = WrappedComponent => { // 定义包装组件 class WithResultsWrapper extends React.Component { render() { return <WrappedComponent {...this.props} />; } } // 映射Redux state到组件props const mapStateToProps = state => { return { results: state.results }; }; // 在这里完成connect和包装组件的绑定 return connect(mapStateToProps)(WithResultsWrapper); }; export default withResults;
这样导出的withResults就是一个标准的HOC:它接收目标组件后,会先创建包装组件,再通过connect把Redux的results注入到props中,最后返回连接后的组件。
方案二:用函数组合的方式结合connect和HOC
如果你想保持connect和withResults的分离,可以用Redux提供的compose工具(或者手动组合)来按正确顺序组合HOC:
import React from "react"; import { connect } from "react-redux"; import { compose } from "redux"; // 从redux导入compose const withResults = WrappedComponent => { return class extends React.Component { render() { return <WrappedComponent {...this.props} />; } }; }; const mapStateToProps = state => { return { results: state.results }; }; // compose会从右到左执行HOC:先让withResults包裹组件,再用connect连接Redux export default compose( connect(mapStateToProps), withResults );
或者不用compose,手动组合:
export default WrappedComponent => connect(mapStateToProps)(withResults(WrappedComponent));
这种写法的效果和方案一一致,都是先让目标组件经过withResults包装,再和Redux store连接。
验证修复
修改完HOC代码后,你原来的PrimaryResults导出代码不需要改动:
export default WithResults(PrimaryResults);
此时WithResults是一个正常的HOC函数,它会把Redux中的results注入到PrimaryResults的props中,同时你的组件逻辑也能正常执行了。
内容的提问来源于stack exchange,提问作者Tsabary

