Setting the file. One moment.
Skill 04 · Vercel React Native Skills
Subchapter 4.9
rules/design-system-compound-components.mdMarkdown2 KBView on GitHub
Don’t create components that can accept a string if they aren’t a text node. If
a component can receive a string child, it must be a dedicated *Text
component. For components like buttons, which can have both a View (or
Pressable) together with text, use compound components, such a ,
, and .
ButtonButtonTextButtonIconIncorrect (polymorphic children):
import { Pressable, Text } from 'react-native'
type ButtonProps = {
children: string | React.ReactNode
icon?: React.ReactNode
}
function Button({ children, icon }: ButtonProps) {
return (
<Pressable>
{icon}
{typeof children === 'string' ? <Text>{children}</Text> : children}
</Pressable>
)
}
// Usage is ambiguous
<Button icon={<Icon />}>Save</Button>
<Button><CustomText>Save</CustomText></Button>Correct (compound components):
import { Pressable, Text } from 'react-native'
function Button({ children }: { children: React.ReactNode }) {
return <Pressable>{children}</Pressable>
}
function ButtonText({ children }: { children: React.ReactNode }) {
return <Text>{children}</Text>
}
function ButtonIcon({ children }: { children: React.ReactNode }) {
return <>{children}</>
}
// Usage is explicit and composable
<Button>
<ButtonIcon><SaveIcon /></ButtonIcon>
<ButtonText>Save</ButtonText>
</Button>
<Button>
<ButtonText>Cancel</ButtonText>
</Button>