pixelSlayer pixelSlayer - 1 month ago 7
React JSX Question

React not rendering multiple components through factory function

The problem is the following, i have a factory:

import React from 'react';

export default (componentFactory) =>
{
return Component =>
{
class Factory extends React.Component
{
render()
{
let { state, props } = this;
return componentFactory({ state, props }, Component);
}
}

return Factory;
};
}


and then a simple Page component wrapper:

import React from 'react';

const Page = ({children, appState}) =>
(
<section>
{React.cloneElement(children, {appState})}
</section>
);


export default Page;


So, in order to create a HomePage, i use HomeFactory likewise:

import React from 'react';
import Factory from '../Factory';

import HeroBanner from '../Banner/HeroBanner';

const HomeFactory = ({state, props}, HomePage) =>
{
return <HomePage {...props} {...state} >
<HeroBanner />
</HomePage>;
};

export default Factory(HomeFactory);


The final code for the HomePage component that is being mounted, is then as follows:

import React from 'react';
import Page from '../Page';

import HomeFactory from '../HomeFactory';

const HomePage = ({children, appState}) =>
{
return (
<Page appState={appState}>
{children}
</Page>
);
};

export default HomeFactory(HomePage);


The problem seems to be the HomeFactory component, in which i put:

return <HomePage {...props} {...state} >
<HeroBanner />
</HomePage>;


as per example given, and this works 100% correctly, however, when i try to put multiple components in form of array or just many components nested in, like:

return <HomePage {...props} {...state} >
<HeroBanner />
<HeroBanner />
<HeroBanner />
</HomePage>;


I am getting the following error:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.


Basically, the Page wrapper component is getting properties passed in as children of its parent component HomePage, and these are taken from the factory method.

The question is what is happening implicitly with JSX that I cannot do the following?

Answer

In your Page component you need to use cloneElement along with Children.map when you pass multiple children (this.props.children is then a special array-like object)

See this answer: stackoverflow.com/a/38011851/3794660 for more details.

Comments