Reputation: 77
I want to dynamically select a react component from a object with a key
import React, {useState, useEffect} from 'react'
import ComponentA from '@components/ComponentA';
import ComponentB from '@components/ComponentB';
const DynamicComponent: React.FC = ({key}) => {
const [Component, setComponent] = useState<any>();
const COMPONENTS = {
COMPONENT_A: ComponentA,
COMPONENT_B: ComponentB,
};
useEffect(() => {
if (key) setComponent(COMPONENTS[key])
}, [key]);
return Component ? React.createElement(Component) : null;
};
With this i get a type error on COMPONENTS[key]
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ COMPONENT_A: FC<{}>; }'.
No index signature with a parameter of type 'string' was found on type '{ COMPONENT_A: FC<{}>; }'.
How do i type this correctly?
Upvotes: 2
Views: 1051
Reputation: 77
I found the answer here: https://stackoverflow.com/a/55014391
Typing the COMPONENTS object fixed my problem.
import React, {useState, useEffect} from 'react'
import ComponentA from '@components/ComponentA';
import ComponentB from '@components/ComponentB';
const DynamicComponent: React.FC = ({key}) => {
const [Component, setComponent] = useState<any>();
const COMPONENTS: {[key: string]: React.FC<any>} = {
COMPONENT_A: ComponentA,
COMPONENT_B: ComponentB,
};
useEffect(() => {
if (key) setComponent(COMPONENTS[key])
}, [key]);
return Component ? React.createElement(Component) : null;
};
Upvotes: 1
Reputation: 306
You're missing default value for useState
You can use null as default value:
useState(null)
Like this:
const [Component, setComponent] = useState<any>(null);
Upvotes: 1
Reputation: 1325
You need define PropTypes for your component, also type of Key.
import React, {useState, useEffect} from 'react'
import ComponentA from '@components/ComponentA';
import ComponentB from '@components/ComponentB';
type Key = "COMPONENT_A" | "COMPONENT_B"
type Props = { key: Key }
const DynamicComponent: React.FC<Props> = ({key}) => {
const [Component, setComponent] = useState<any>();
const COMPONENTS = {
COMPONENT_A: ComponentA,
COMPONENT_B: ComponentB,
};
useEffect(() => {
if (key) setComponent(COMPONENTS[key])
}, [key]);
return Component ? React.createElement(Component) : null;
};
Upvotes: 1