I'm trying to hanlde props of passed React Element in Factory but I cannot because I receive typescript error:
TS2604: JSX element type 'this.extraBlock' does not have any construct or call signatures.
My Child component:
interface BlockTitleType {
title: string,
children?: React.ReactNode
}
const MainContactBlock: React.FC<BlockTitleType> = (e: BlockTitleType) => <div>{e.title}</div>;
My Parent component:
const factory = new TabBlockFactory(MainContactBlock);
const ContactBlocks: React.FC = () => <>factory.createBlock('test title')}</>
My factory:
interface BlockType {
title: string
}
class TabBlockFactory {
private mainBlock: React.ReactNode;
constructor(mainBloc: React.FC) {
this.mainBlock = mainBloc;
}
createBlock = ({title}: BlockType) => {
// the error occurs here:
// TS2604: JSX element type 'this.extraBlock' does not have any construct or call signatures.
return <this.mainBlock title={title}/>
}
}
it works only with any type, but it's an antipatern :(
I also tried types as React.Component, React.ReactElement, JSX.Elements
I've tried all 3 fixes from @Yuval:
Has no effect - renamed class variable this.mainBlock -> this.MainBlock
;
Has no effect - introduced intermediate variable
const Component = this.mainBloc;
return <Component title={title} />;
private MainBlock: React.ComponentType<BlockTitleType>;
as @Yuval proposed.TLDR: working sandbox link
So there is a few problems with your code:
you are using the type React.ReactNode
to represent a component, and it doesn't work. I recommend that to represent a React Component you use React.ComponentType<PROPS>
.
So in your case in will be ComponentType<BlockTitleType>
the line <this.mainBlock />
is problematic, react doesn't like Components that do not start with an Upper case and also its an access to a this
attribute at the same time, so separate that into 2 lines like so:
const Component = this.mainBloc;
return <Component title={title} />;
other than that I added some small syntax fixes and small improvements
{
in ContactBlocks