reactjs - Utilizarea HOC-urilor pe componente React generice în Typescript
Am un component React care este tipizat cu un generic. Acest component, la rândul său, este extins cu un component de ordin superior (în acest caz, redux-form). Iată o versiune redusă a clasei mele și a HOC-ului aplicat:
import * as React from "react";
interface MyFormProps<D> {
prop: D;
form: string;
}
class MyForm<D> extends React.Component<MyFormProps<D>, {}> {
render(): JSX.Element {
return (
<form>
{this.props.prop}
</form>
);
}
}
export const ConnectedMyForm = reduxForm({} as Config<any, {}, {}>)(MyForm);
Apoi încerc să creez o versiune tipizată a componentului meu într-un alt component.
import { ConnectedMyForm } from "./my-form";
interface FormType {
// Form props here
}
type TypedForm = new () => ConnectedMyForm<FormType>;
const TypedForm = ConnectedMyForm as TypedForm;
Pentru a putea să-l folosești în TSX astfel:
<TypedForm />
Această metodă funcționează absolut bine pe un alt Component pe care l-am construit și care nu are aplicat HOC, dar aici primesc următoarea eroare:
eroare TS2304: Nu se poate găsi numele 'ConnectedMyForm'.
pe linia type TypedForm=new() => ConnectedMyForm<FormType>;.
Acest lucru se întâmplă doar când aplic funcția HOC componentului meu. Presupun că se datorează faptului că nu am specificat tipul generic pe versiunea conectată a formularului. Dar cum aș specifica acel tip?
Răspuns #1
De ce să nu creezi pur și simplu un hoc/EnhancedForm ca:
import * as React from 'react';
interface EnhancedProps {
name: string;
}
export default <T extends {}>(Component: React.StatelessComponent<T> | React.ComponentClass<T>):
React.StatelessComponent<T & EnhancedProps> =>
(props: T & EnhancedProps) => {
return <Component { ...props } />
}
Și apoi folosește acel HoC în SimpleForm astfel:
const SimpleForm = props => {
const handleSubmit = () => { alert("Validated"); }
const { pristine, reset, submitting } = props
return (
<form onSubmit={ handleSubmit }>
<div>
<label>First Name</label>
....
</form>
)
}
export default EnhancedForm(reduxForm({
form: 'simple' // a unique identifier for this form
})(SimpleForm))
Și în final folosește-l așa cum descrii:
render() {
return (
<SimpleForm name="SimpleName" />
);
}
