Untrack
untrack body reads values without making them dependencies of the surrounding computation. Use it when you need a value but do not want changes to that value to trigger another run.
Unlike Peek, an untracked read of memo.Value refreshes a stale memo.
Change Ignored, then Tracked. Only the tracked signal has an edge to the effect, so only its write runs the effect again. That run still reads the current ignored value.
Test your understanding
Does writing ignored run the effect again? Does writing tracked? What value does the final untracked read of doubled return?
let untrackRuns, untrackedMemoValue =
use graph = new Graph ()
use _ = graph.Activate ()
let tracked = createSignal 0
let ignored = createSignal 0
let mutable runs = 0
createEffect (fun () ->
tracked.Value |> ignore
untrack (fun () -> ignored.Value) |> ignore
runs <- runs + 1)
ignored.Value <- 1 // no re-run
tracked.Value <- 1 // re-run
let source = createSignal 1
let doubled = createMemo (fun _ -> source.Value * 2)
doubled.Value |> ignore
source.Value <- 21
runs, untrack (fun () -> doubled.Value)
printfn "effect runs: %d, untracked stale memo read: %d" untrackRuns untrackedMemoValue
Answer
effect runs: 2, untracked stale memo read: 42
The effect runs initially and when tracked changes. The read of ignored records no dependency. The final read recomputes doubled, so it returns 42.
Nested untrack calls
Calls nest. Tracking resumes after the outermost untrack returns.