useEffect
For more detailed information about React concepts and APIs, please refer to the official documentation for useEffect.
useEffect
lets you run side effects in your components, such as data fetching, subscriptions, or logging. Effects run after every render by default, but you can control when they run using a dependencies array.
Effects are useful for running code that interacts with the outside world, such as APIs, timers, or logging. You can also return a cleanup function to run when the component unmounts or before the effect runs again.
[<ReactComponent(true)>]
let UseEffect() =
let count, setCount = React.useState(0)
// useEffect: run side effect when count changes
React.useEffect((fun () ->
JS.console.log($"Count changed to {count}")
// Optional cleanup function
fun () -> JS.console.log("Cleanup effect")
), [| box count |])
Html.div [
Html.button [
prop.text $"Clicked {count} times"
prop.onClick (fun _ -> setCount(count + 1))
]
Html.p [ prop.text "Open the browser console to see useEffect logs when count changes." ]
]
Open the browser console to see useEffect logs when count changes.
Show code
module Example.UseEffect
open Feliz
[<ReactComponent(true)>]
let UseEffect() =
let count, setCount = React.useState(0)
// useEffect: run side effect when count changes
React.useEffect((fun () ->
Fable.Core.JS.console.log($"Count changed to {count}")
// Optional cleanup function
fun () -> Fable.Core.JS.console.log("Cleanup effect")
), [| box count |])
Html.div [
Html.button [
prop.text $"Clicked {count} times"
prop.onClick (fun _ -> setCount(count + 1))
]
Html.p [ prop.text "Open the browser console to see useEffect logs when count changes." ]
]
UseEffectOnce
useEffectOnce
is a specialized version of useEffect
that automatically passes an empty array as dependencies, therefore running only once when the component mounts.
Refresh this component to see the load effect run once
This simulates loading data on mount
Show code
module Example.UseEffectOnce
open Feliz
[<ReactComponent(true)>]
let EffectWithAsyncOnce() =
let (isLoading, setLoading) = React.useState(false)
let (content, setContent) = React.useState("")
let loadData() = async {
setLoading true
do! Async.Sleep 1500
setLoading false
setContent "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
}
React.useEffectOnce(loadData >> Async.StartImmediate)
Html.div [
Html.p "Refresh this component to see the load effect run once"
Html.p "This simulates loading data on mount"
if isLoading
then Html.h1 "Loading..."
else Html.h1 content
]
UseEffect with IDisposable
If your effect returns an IDisposable
, Feliz will automatically call its Dispose
method when the component unmounts or before the effect runs again.
Open the browser console to see useEffect logs when count changes.
Show code
module Example.UseEffectDisposable
open Feliz
[<ReactComponent(true)>]
let UseEffect() =
let count, setCount = React.useState(0)
// useEffect: run side effect when count changes
React.useEffect((fun () ->
Fable.Core.JS.console.log($"Count changed to {count}")
// Optional cleanup function
{ new System.IDisposable with member this.Dispose() = Fable.Core.JS.console.log("Cleanup effect") }
), [| box count |])
Html.div [
Html.button [
prop.text $"Clicked {count} times"
prop.onClick (fun _ -> setCount(count + 1))
]
Html.p [ prop.text "Open the browser console to see useEffect logs when count changes." ]
]