Skip to content

Instantly share code, notes, and snippets.

@kyleshevlin
Last active January 23, 2021 10:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyleshevlin/25f618714691dbb791c4474ebf6dff51 to your computer and use it in GitHub Desktop.
Save kyleshevlin/25f618714691dbb791c4474ebf6dff51 to your computer and use it in GitHub Desktop.
`as` prop and the facade pattern
// Sometimes you'll have a component that you want to allow the consumer
// to render a different HTML element for semantic purposes. Use an `as`
// prop and a facade pattern to make it happen.
export function CallToAction({as = 'button', ...props}) {
return <CallToActionFacade as={as} {...props} />
}
function CallToActionFacade({ as, ...props }) {
switch (as) {
case 'button':
return <button type="button" {...props} />
case 'a':
case 'link':
return <a {...props} />
default:
throw new Error(`The 'as' prop, ${as}, is not supported by CallToAction`)
}
}
// If you're using a type system, you can even do the work to ensure
// that the correct props are supplied depending on the `as` prop!
<CallToAction
as="button" // unnecessary because of default parameter, but useful for the example
onClick={() => { console.log('heyo!') }}
>
Heyo!
</CallToAction>
// or...
<CallToAction
as="a"
href="https://kyleshevlin.com"
target="_blank"
rel="noreferrer noopener"
>
Heyo!
</CallToAction>
// Enjoy!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment