Skip to main content

Conditional Rendering

F# syntax allows for multiple solutions to conditional rendering in React components. Here are some of the most common patterns:

info

You can use any F# pattern normally used for conditional logic in your React components.

  • Apple ⚠️
    1 left in store
  • Banana
    Out of stock
  • Orange
    10 left in store
  • Grape ⚠️
    3 left in store
  • Pineapple
    Out of stock
  • Mango
    7 left in store
  • Blueberry
    Out of stock
  • Raspberry
    20 left in store
Show code
module Example.ConditionalRendering

open Feliz

Fable.Core.JsInterop.importSideEffects "./conditional-rendering.css"

type ConditionalRendering =

[<ReactComponent>]
static member Item(text: string, count: int) =
let isMany = count > 5
Html.li [
prop.style [
style.display.flex;
style.justifyContent.spaceBetween;
style.alignItems.center
]
prop.children [
Html.div [
Html.text text
if not isMany then Html.text " ⚠️"
]
Html.small [
prop.className [
if isMany then "text-green-500" else "text-red-500"
]
prop.textf "%d left in store" count
]
]
]

[<ReactComponent>]
static member OutOfStock(text: string) =
Html.li [
prop.style [
style.display.flex;
style.justifyContent.spaceBetween;
style.alignItems.center
]
prop.children [
Html.div [
prop.style [ style.textDecorationLine.lineThrough ]
prop.text text
]
Html.small "Out of stock"
]
prop.className "text-gray-500"
]

[<ReactComponent(true)>]
static member Example() =
let data = [
"Apple", Some 1
"Banana", None
"Orange", Some 10
"Grape", Some 3
"Pineapple", None
"Mango", Some 7
"Blueberry", None
"Raspberry", Some 20
]

Html.ul [
for text, count in data do
match count with
| Some count -> ConditionalRendering.Item(text, count)
| None -> ConditionalRendering.OutOfStock(text)
]

if ... else

The classic if ... else expression can be used to conditionally include elements in the render output. Inside lists you can omit the else case if you don't want to do anything in that case. If you have multiple if ... else cases you can use elif to chain them together.

Html.div [
Html.text text
if not isMany then Html.text " ⚠️" // inside a list `else` case can be omitted
]

// in this case we cannot omit `else` case
let className = if isMany then "text-green-500" else "text-red-500"
// but we can also use the expression directly
prop.className [
if isMany then "text-green-500" else "text-red-500"
]

if count > 5 then
"Many"
elif count > 10 then
"A lot"
else
"Few"

Pattern matching

Pattern matching is a powerful feature of F# that can be used for conditional rendering. It allows you to match against specific values or patterns and render different elements based on the match.

It provides a clean and expressive way to handle multiple conditions, while at the same time allowing for deconstruction logic on some types (like option, list, tuple, and discriminated unions).


match (Some 5) with // option
| Some count -> Html.div [ Html.textf "%d left in store" count ]
| None -> Html.div [ Html.text "Out of stock" ]

type Person = { Name: string option; IsSignedIn: bool }

match { Name = Some "Alice"; IsSignedIn = true } with // record type
| { IsSignedIn = true; Name = name } -> Html.div [ Html.textf "Welcome back, %s!" name ]
| { IsSignedIn = false } -> Html.div [ Html.textf "Hello, please sign in." ]

match [1; 2; 3] with // list
| [] -> Html.div [ Html.text "Empty list" ]
| [x] -> Html.div [ Html.textf "Single item: %d" x ]
| [x; y] -> Html.div [ Html.textf "Two items: %d and %d" x y ]
| x :: xs -> Html.div [ Html.textf "Head: %d, Tail length: %d" x (List.length xs) ]