reactjs - Bruke HOCs på generiske Typescript React-komponenter
Jeg har en React-komponent som er typet med en generisk. Den komponenten blir videre utvidet med en høyere ordens komponent (i dette tilfellet, redux-form). Her er en nedstrippet versjon av klassen min og HOC-en som blir brukt:
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);
Deretter prøver jeg å lage en skrevet versjon av komponenten min i en annen komponent.
import { ConnectedMyForm } from "./my-form";
interface FormType {
// Form props here
}
type TypedForm = new () => ConnectedMyForm<FormType>;
const TypedForm = ConnectedMyForm as TypedForm;
For å kunne bruke det i TSX som følger:
<TypedForm />
Denne metoden fungerer helt fint på en annen komponent jeg har laget som ikke har HOC brukt, men her får jeg følgende feil:
feil TS2304: Kan ikke finne navnet 'ConnectedMyForm'.
på linjen type TypedForm=new() => ConnectedMyForm<FormType>;.
Dette skjer bare når jeg bruker HOC-funksjonen på komponenten min. Jeg antar det er fordi jeg ikke har spesifisert den generiske typingen på den tilkoblede versjonen av skjemaet. Men hvordan ville jeg spesifisert den typingen?
Svar #1
Hvorfor ikke bare lage en hoc/EnhancedForm som:
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 } />
}
Og så bruk bare den HoC i din SimpleForm som:
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))
Og til slutt bruk det slik du beskriver:
render() {
return (
<SimpleForm name="SimpleName" />
);
}
