我遇到了一个我无法解决的问题。对于项目,我们使用React使用以下代码(简化)从JSON输入生成布局:
function generateComponents(children, params) {
let comps = [];
if (!children || children && children.length === 0) {
return [];
}
forEach(children, (comp) => {
let compName = comp.component;
let createdComp;
switch (compName) {
case 'test1':
createdComp = TestOne(Object.assign({}, comp, params));
break;
case 'test2':
createdComp = TestTwo(Object.assign({}, comp, params));
break;
}
comps.push(createdComp)
}
}
return comps.length === 1 ? comps[0] : comps;
}
这很好用,并且正确生成了布局。我们希望更进一步,将createdComp
包装在Higher Order Component
中。我们通过以下方式实现了这一点:
function generateComponents(children, params) {
// see above for implementation
let component;
if (condition)
component = testingHOC(createdComp);
else
component = createdComp
comps.push(component);
}
// TestingHOC.js
export function testingHoc(WrappedComponent) {
console.log('wrapped')
return class TestingHoc extends Component {
render() {
console.log('props TestingHOC', this.props);
return ( <WrappedComponent { ...this.props} />);
}
}
};
这打破了我们的组件生成。代码什么都不返回。记录的唯一内容是console.log('wrapped')
,从不调用类的render函数。我们在这里缺少什么?
编辑: 渲染类的渲染方法:
render() {
const children = this.state.children;
const {params} = this.props;
const arrChildren = isArray(children) ? children : [children];
let comps = generateComponents(arrChildren, params || {});
if (isArray(comps)) {
return (
<ViewComponent>
{comps}
</ViewComponent>
);
} else {
return comps;
}
}
编辑2:
带有testingHoc的{comps}
的Console.log
Console.log {comps}
没有 testingHoc
编辑3
添加了ViewComponent的代码:
import React from 'react';
const ViewComponent = (props) => (
<div {...props}/>
);
export default ViewComponent;
答案 0 :(得分:4)
您面临的问题是由于React element and a React component.
之间的固有差异当您不使用HOC时,您正在创建一个可以通过第一个console.log映像看到的React元素。这是reconciliation发生后的输出。
当您使用HOC时,您的HOC会返回一个组件,该组件在您的第二个console.log映像中显示为test(props)
函数。
要使用HOC增强组件具有相同的功能,您需要将generateComponents
功能中的代码更改为
if (condition){
let Comp = testingHOC(createdComp);
component = <Comp/>;
}
答案 1 :(得分:1)
尝试
...
return (
<ViewComponent>
{comps.map((Comp) => <Comp />)}
</ViewComponent>
);
...
或
...
return (
<ViewComponent>
{comps.map((comp) => comp())}
</ViewComponent>
);
...