# 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.

<div class="partas-solid-card partas-solid-card--map">

<div class="partas-solid" data-partas-page="pa595210349" data-partas-cell="c1"></div>

</div>

::::details Test your understanding

Does writing `ignored` run the effect again? Does writing `tracked`? What value does the final
untracked read of `doubled` return?

```fsharp
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
```

:::details Answer

```text
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`.

:::
::::

:::details Nested untrack calls
Calls nest. Tracking resumes after the outermost `untrack` returns.
:::
