Conditional Rendering
F# syntax allows for multiple solutions to conditional rendering in React components. Here are some of the most common patterns:
You can use any F# pattern normally used for conditional logic in your React components.
- Apple ⚠️1 left in store
- BananaOut of stock
- Orange10 left in store
- Grape ⚠️3 left in store
- PineappleOut of stock
- Mango7 left in store
- BlueberryOut of stock
- Raspberry20 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) ]