Vue Academy · Lesson

Advanced Reactivity: shallowRef and triggerRef

shallowRef for performance, markRaw to exclude from reactivity, triggerRef for manual trigger.

Lesson 1 of 413 steps

Advanced Reactivity: shallowRef and triggerRef is a free Vue Academy lesson on CoddyKit. This is lesson 1 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, and your progress syncs across the web and the CoddyKit app. The Vue Academy course includes 4 lessons in total.

Beyond ref and reactive

Vue’s deep reactivity is convenient but not always what you want. For large objects or external instances, deep tracking is wasteful. Vue offers shallowRef, triggerRef, and markRaw for fine control.

How ref Tracks Deeply

A normal ref holding an object makes the entire object deeply reactive — mutating any nested property triggers updates. Great for small state, costly for big structures.

import { ref } from "vue"

const user = ref({ name: "Ada", prefs: { theme: "dark" } })
user.value.prefs.theme = "light" // triggers update (deep)

shallowRef: Only .value Is Reactive

shallowRef tracks reassignment of .value but does not track mutations inside the held value. Inner changes do not trigger renders.

import { shallowRef } from "vue"

const state = shallowRef({ count: 0 })
state.value.count++        // does NOT trigger update
state.value = { count: 1 } // DOES trigger (new .value)

When to Use shallowRef

Use it for large immutable-ish data you replace wholesale, or to wrap external objects (a chart instance, a big dataset) where deep tracking adds overhead with no benefit.

const chart = shallowRef(null)
// chart.value = new Chart(...) replaces wholesale

The Deep Mutation Problem

Sometimes you DO mutate inside a shallowRef (for performance) but still need a re-render at a controlled moment. Vue cannot see the change, so the UI goes stale.

const list = shallowRef([1, 2, 3])
list.value.push(4) // mutated, but no update fires

triggerRef: Force an Update

triggerRef manually forces effects depending on a shallow ref to re-run, after you have mutated its contents. You batch many mutations, then trigger once.

import { shallowRef, triggerRef } from "vue"

const list = shallowRef([1, 2, 3])
list.value.push(4)
list.value.push(5)
triggerRef(list) // now the UI updates

A Performance Pattern

The pattern: hold a big structure in shallowRef, mutate it freely without per-change reactivity cost, then call triggerRef once when you want the view to reflect the batch.

function bulkUpdate(rows) {
  for (const r of rows) data.value.push(r) // cheap
  triggerRef(data)                         // one update
}

markRaw: Opt Out Entirely

markRaw marks an object so Vue will never make it reactive, even inside a reactive or normal ref. Use it for third-party class instances that should not be proxied.

import { markRaw, reactive } from "vue"

const state = reactive({
  map: markRaw(new ThirdPartyMap()),
})
// state.map is the raw instance, never a proxy

Why markRaw Matters

Wrapping complex class instances (maps, editors, websockets) in a reactive proxy can break their internal references or cause subtle bugs. markRaw keeps them untouched while still living inside reactive state.

Combining the Tools

These compose: a shallowRef holding a markRaw instance gives you a slot you can replace reactively, with an inner object Vue never proxies — ideal for external integrations.

const editor = shallowRef(null)
function init(el) {
  editor.value = markRaw(new CodeEditor(el))
}

Reactivity Cost vs Control

The trade-off: deep reactivity is effortless but heavier; shallow APIs give you control and performance at the cost of triggering updates yourself. Reach for them only when profiling shows a need.

Quick Check

Check your understanding of advanced reactivity.

Recap

You learned advanced reactivity controls:

  • shallowRef reacts only to .value reassignment, not inner mutations — good for large or external data.
  • triggerRef manually forces updates after mutating a shallow ref’s contents (batch then trigger once).
  • markRaw permanently opts an object out of reactivity, ideal for third-party class instances.
  • These give performance and control at the cost of triggering updates yourself.
Free to start

Learn HTML with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
42
Lessons
156

Frequently Asked Questions

Is the “Advanced Reactivity: shallowRef and triggerRef” lesson free?

Yes — any 3 lessons of the Vue Academy learning path, including “Advanced Reactivity: shallowRef and triggerRef”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Vue Academy course includes 4 lessons in total.

What will I learn in “Advanced Reactivity: shallowRef and triggerRef”?

shallowRef for performance, markRaw to exclude from reactivity, triggerRef for manual trigger. You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Vue Academy?

No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 1 of 4.

How long does the “Advanced Reactivity: shallowRef and triggerRef” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Vue Academy lesson?

Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Advanced Reactivity: shallowRef and triggerRef
  2. Composable Factories and Parameterized Composables
  3. State Machines with XState in Vue
  4. effectScope for Grouped Effects
← Back to Vue Academy