Skip to content

Commit

Permalink
add conditionally rendering components example
Browse files Browse the repository at this point in the history
  • Loading branch information
swyxio authored Sep 24, 2019
1 parent 451aa8a commit 497b724
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions ADVANCED.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ The best tool for creating React + TS libraries right now is [`tsdx`](https://gi
- [Section 1: Reusable Components/Type Utilities](#section-1-reusable-componentstype-utilities)
- [Higher Order Components](#higher-order-components-hocs)
- [Render Props](#render-props)
- [Conditionally Rendering Components](#conditinonally-rendering-components)
- [`as` props (passing a component to be rendered)](#as-props-passing-a-component-to-be-rendered)
- [Typing a Component that Accepts Different Props](#typing-a-component-that-accepts-different-props)
- [Props: One or the Other but not Both](#props-one-or-the-other-but-not-both)
Expand Down Expand Up @@ -119,6 +120,55 @@ export interface Props {

[Something to add? File an issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new/choose).

## Conditionally Rendering Components

Use [type guards](https://basarat.gitbooks.io/typescript/docs/types/typeGuard.html#user-defined-type-guards)!

```tsx
// Button props
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
href?: undefined
}

// Anchor props
type AnchorProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & {
href?: string
}

// Input/output options
type Overload = {
(props: ButtonProps): JSX.Element
(props: AnchorProps): JSX.Element
}

// Guard to check if href exists in props
const hasHref = (props: ButtonProps | AnchorProps): props is AnchorProps => 'href' in props

// Component
const Button: Overload = (props: ButtonProps | AnchorProps) => {
// anchor render
if (hasHref(props)) return <a {...props} />
// button render
return <button {...props} />
}

// Usage
function App() {
return (
<>
{/* 😎 All good */}
<Button target="_blank" href="https://www.google.com">
Test
</Button>
{/* 😭 Error, `disabled` doesnt exist on anchor element */}
<Button disabled href="x">
Test
</Button>
</>
)
}
```

## `as` props (passing a component to be rendered)

`ElementType` is pretty useful to cover most types that can be passed to createElement e.g.
Expand Down

0 comments on commit 497b724

Please sign in to comment.