Reputation: 1650
I'm trying to make a React component which takes in a generic type parameter which will be part of its prop type.
I want a solution that would look something like this:
interface TestProps<T> {
value: T;
onChange: (newValue: T) => void;
}
const Test: React.FC<TestProps<T>> = (props) => (
<span>{props.value}</span>
);
I have seen that there is support for this in TypeScript 2.9 and I'm on 4.3.5.
Usage of this would look like this:
const Usage: React.FC = () => (
<div>
<Test<Obj>
value={{ name: 'test' }}
onChange={(newValue) => {
console.log(newValue.name);
}}
/>
</div>
);
Code sandbox: https://codesandbox.io/s/react-typescript-playground-forked-8hu13?file=/src/index.tsx
Upvotes: 40
Views: 46165
Reputation: 208
This is how you create a generic component using an arrow function.
const StyledDropdown = <T,>(props: React.PropsWithChildren<Props<T>>) => {
return (
<></>
);
};
export default StyledDropdown;
Upvotes: 0
Reputation: 32757
In my case it was like the following codes:
export interface FormProps<T> {
validator?: AnyObjectSchema;
onSubmit?: (data: T) => void;
}
const Form = <T = any,>({
children,
validator,
}: PropsWithChildren<FormProps<T>>): JSX.Element => {
~~~
And in usage:
type MyType = ...
<Form<MyType>
validation={something}
onSubmit={handleSomething}
>
<SomeCompo />
<AnotherSomeCompo />
</Form>
Upvotes: 16
Reputation: 33111
You need to rewrite your Test
component in this way
const Test= <T,>(props:TestProps<T>) => (
<span>Some component logic</span>
);
Can you show the same with React.FC<TestProps>? It is impossible to do with
FC
.
This is FC
implementation:
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
// ... other static properties
}
As you might have noticed, FC
is a function type, not type of props.
UPDATE
You can create higher order function, but I'm not sure if it worth it
const WithGeneric = <T,>(): React.FC<TestProps<T>> =>
(props: TestProps<T>) => (
<span>Some component logic</span>
);
const Test = WithGeneric<Obj>()
Upvotes: 35
Reputation: 169416
The easiest way is to make the generic FC a regular function, not an arrow function. (React.PropsWithChildren<>
emulates what React.FC
does to your props
type.)
function Test<T>(props: React.PropsWithChildren<TestProps<T>>) {
return <span>Some component logic</span>;
}
Upvotes: 34