TypeScript and React: Pass component in props and return it from a function
ReactNode
is React element type, while component
prop is expected to be React component.
It likely should be:
export interface Props {
component: React.ComponentType;
handleSubmit(): void;
}
renderForm has to return a ReactNode, so I can't change ReactNode to ComponentType (the latter would resolve the JSX error).
component
prop and renderForm
return type aren't connected. The former is a component and the latter is an element.
Comments
-
J. Hesters almost 2 years
I'm writing a Form component with React and TypeScript. I use Formik for the form logic. I want to pass the
<Form />
component a specific form as a prop and render it. Here is what I tried:import { Formik, FormikProps } from "formik"; import React, { PureComponent, ReactNode } from "react"; export interface Props { component: ReactNode; // TODO: Change to one of LoginForm or RegisterForm. handleSubmit(): void; } export class Form extends PureComponent<Props> { renderForm = (formikProps: FormikProps<any>): ReactNode => { const { component: FormComponent } = this.props; return <FormComponent {...formikProps} />; }; render() { const { handleSubmit } = this.props; return <Formik render={this.renderForm} />; } } export default Form;
The problem is that the line where I return the
<FormComponent />
throws the error:[ts] JSX element type 'FormComponent' does not have any construct or call signatures.
renderForm
has to return a ReactNode, so I can't changeReactNode
toComponentType
(the latter would resolve the JSX error).How would one do this in TypeScript?
Edit So I got it working by doing this (thanks to estus):
import { Formik, FormikProps } from "formik"; import React, { PureComponent, ReactElement } from "react"; export interface Props { component: React.ComponentType<any>; // TODO: Change to one of LoginForm or RegisterForm. handleSubmit(): void; } export class Form extends PureComponent<Props> { renderForm = (formikProps: FormikProps<any>): ReactElement<any> => { const { component: FormComponent } = this.props; return <FormComponent {...formikProps} />; }; render() { const { handleSubmit } = this.props; return <Formik render={this.renderForm} />; } } export default Form;