useCallback
For more detailed information about React concepts and APIs, please refer to the official documentation for useCallback.
useCallback
is a hook that lets you memoize callback functions so they are not recreated on every render. This is useful when passing callbacks to child components to prevent unnecessary rerenders.
[<ReactComponent(true)>]
let UseCallback() =
let count, setCount = React.useState(0)
let increment = React.useCallback((fun () -> setCount(count + 1)), [| box count |])
// ...
In the following example the increment
function is memoized using useCallback
and passed to the ChildComponent
. This prevents ChildComponent
from rerendering unless increment
changes, which only happens when count
changes. Therefore updating theme
will not cause ChildComponent
to rerender.
The increment function is memoized using useCallback and passed to the child.
Child rendered 0 times
Show code
module Example.UseCallback
open Feliz
[<ReactMemoComponent>] // memoizes component to prevent rerender whenever parent rerenders
let ChildComponent(onClick: unit -> unit) =
let renderCount = React.useRef(0)
React.useEffect(fun () ->
renderCount.current <- renderCount.current + 1
)
Html.div [
Html.button [
prop.text "Child Button"
prop.onClick (fun _ -> onClick())
]
Html.p [ prop.text $"Child rendered {renderCount.current} times" ]
]
[<ReactComponent(true)>]
let UseCallback() =
let count, setCount = React.useState(0)
let theme, setTheme = React.useState("light")
// Memoize the callback so ChildComponent only rerenders when count changes
let increment = React.useCallback((fun () -> setCount(count + 1)), [| box count |])
Html.div [
Html.button [
prop.text "Toggle Theme"
prop.onClick (fun _ ->
if theme = "light" then setTheme("dark")
else setTheme("light"))
]
Html.div theme
Html.button [
prop.text $"Increment"
prop.onClick (fun _ -> increment())
]
Html.div count
Html.p [ prop.text "The increment function is memoized using useCallback and passed to the child." ]
ChildComponent increment
]
Feliz specifics
The API is similar to React's JavaScript version, but the dependencies array must be of type obj[]
due to F#'s strong typing.