如何在绕过条件渲染的同时将变量作为反应组件传递?
How do I pass a variable as a react component while bypassing conditional render?
import { ReactComponent as GreenIcon } from '../assets/green.svg'
import { ReactComponent as YellowIcon } from '../assets/yellow.svg'
import { ReactComponent as RedIcon } from '../assets/red.svg'
const GreenIconMemoized = memo(GreenIcon)
const YellowIconMemoized = memo(YellowIcon)
const RedIconMemoized = memo(RedIcon)
const STATUSES = ['ready', 'delay', 'stop']
const icons = new Map([
['ready', GreenIconMemoized],
['delay', YellowIconMemoized],
['stop', RedIconMemoized]
])
const [sampleStatus, setSampleStatu] = useObserver(() => [
sampleSTORE.sampleStatus,
sampleSTORE.setSampleStatus
])
const sampleArray: ComponentType[] = useMemo(() => {
return STATUSES.map((status: string) => {
const Icon = icons.get(status)
return {
id: status,
label: status,
isSelected: status === sampleStatus,
onSelect: (): void => {
setSampleStatus(status)
},
leftComponent: Icon ? <Icon /> : undefined
}
})
}, [sampleStatus])
在上面的代码中,在不需要条件渲染的情况下将图标值作为反应组件传递的最佳方法是什么? STATUSES 和图标都被硬编码到系统中,因此实际上并不是可变的——永远不会达到 else 条件。但是,如果我尝试通过,例如:
...
leftComponent: <Icon />
...
我收到错误消息“JSX 元素类型 'Icon' 没有任何构造或调用签名。”
我建议使用对象而不是地图。这样,打字稿就可以确切地知道哪些键是有效的,从而知道 undefined
是不可能的(只要您提供有效的键)。
const STATUSES = ['ready', 'delay', 'stop'] as const;
const icons = {
ready: GreenIconMemoized,
delay: YellowIconMemoized,
stop: RedIconMemoized
}
//...
return STATUSES.map((status) => {
const Icon = icons[status];
// ...
leftComponent: <Icon />
// ...
请注意,我在状态上使用了 as const
。这会导致打字稿将类型推断为 readonly ["ready", "delay", "stop"]
,而不是 string[]
。这意味着稍后,当您映射数组时,status
是 "ready" | "delay" | "stop"
类型,而不是 string
,因此您已经向 typescript 证明您只能访问有效键。
如果您愿意,可以更明确地进行类型设置,如:
const STATUSES: ("ready" | "delay" | "stop")[] = ['ready', 'delay', 'stop'];
// ...
return STATUSES.map((status: "ready" | "delay" | "stop") => {
// OR:
const STATUSES: (keyof typeof icons)[] = ['ready', 'delay', 'stop'];
// ...
return STATUSES.map((status: keyof typeof icons) => {
import { ReactComponent as GreenIcon } from '../assets/green.svg'
import { ReactComponent as YellowIcon } from '../assets/yellow.svg'
import { ReactComponent as RedIcon } from '../assets/red.svg'
const GreenIconMemoized = memo(GreenIcon)
const YellowIconMemoized = memo(YellowIcon)
const RedIconMemoized = memo(RedIcon)
const STATUSES = ['ready', 'delay', 'stop']
const icons = new Map([
['ready', GreenIconMemoized],
['delay', YellowIconMemoized],
['stop', RedIconMemoized]
])
const [sampleStatus, setSampleStatu] = useObserver(() => [
sampleSTORE.sampleStatus,
sampleSTORE.setSampleStatus
])
const sampleArray: ComponentType[] = useMemo(() => {
return STATUSES.map((status: string) => {
const Icon = icons.get(status)
return {
id: status,
label: status,
isSelected: status === sampleStatus,
onSelect: (): void => {
setSampleStatus(status)
},
leftComponent: Icon ? <Icon /> : undefined
}
})
}, [sampleStatus])
在上面的代码中,在不需要条件渲染的情况下将图标值作为反应组件传递的最佳方法是什么? STATUSES 和图标都被硬编码到系统中,因此实际上并不是可变的——永远不会达到 else 条件。但是,如果我尝试通过,例如:
...
leftComponent: <Icon />
...
我收到错误消息“JSX 元素类型 'Icon' 没有任何构造或调用签名。”
我建议使用对象而不是地图。这样,打字稿就可以确切地知道哪些键是有效的,从而知道 undefined
是不可能的(只要您提供有效的键)。
const STATUSES = ['ready', 'delay', 'stop'] as const;
const icons = {
ready: GreenIconMemoized,
delay: YellowIconMemoized,
stop: RedIconMemoized
}
//...
return STATUSES.map((status) => {
const Icon = icons[status];
// ...
leftComponent: <Icon />
// ...
请注意,我在状态上使用了 as const
。这会导致打字稿将类型推断为 readonly ["ready", "delay", "stop"]
,而不是 string[]
。这意味着稍后,当您映射数组时,status
是 "ready" | "delay" | "stop"
类型,而不是 string
,因此您已经向 typescript 证明您只能访问有效键。
如果您愿意,可以更明确地进行类型设置,如:
const STATUSES: ("ready" | "delay" | "stop")[] = ['ready', 'delay', 'stop'];
// ...
return STATUSES.map((status: "ready" | "delay" | "stop") => {
// OR:
const STATUSES: (keyof typeof icons)[] = ['ready', 'delay', 'stop'];
// ...
return STATUSES.map((status: keyof typeof icons) => {