I am facing a problem I can't figure out. For a project we use React to generate a layout from JSON input using the following code (simplified):
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;
}
This works well and the layout is generated correctly. We wanted to take this a step further and wrap the createdComp
in a Higher Order Component
. We implemented that in the following way:
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} />);
}
}
};
This broke our component generation. The code returns nothing. The only thing that gets logged is the console.log('wrapped')
, the render function of the class is never called. What are we missing here?
EDIT: Render method of the render class:
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;
}
}
EDIT 2:
Console.log of {comps}
with the testingHoc
Console.log of {comps}
without the testingHoc
Edit 3
Added the code for ViewComponent:
import React from 'react';
const ViewComponent = (props) => (
<div {...props}/>
);
export default ViewComponent;
The issue you are facing is because of the inherent difference between a React element and a React component.
When you are not using the HOC, you are creating a React element which can be seen by the first console.log image. This is the output after reconciliation has occurred.
When you use the HOC, your HOC returns a component which shows up as the test(props)
function in your second console.log image.
To have the same functionality with your HOC enhanced components, you need to change the code in generateComponents
functions to
if (condition){
let Comp = testingHOC(createdComp);
component = <Comp/>;
}
Try
...
return (
<ViewComponent>
{comps.map((Comp) => <Comp />)}
</ViewComponent>
);
...
or
...
return (
<ViewComponent>
{comps.map((comp) => comp())}
</ViewComponent>
);
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With