Skip to main content

useCallback

Check out the official React docs!

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.

light
0

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.