--- title: Provide/Inject Values Are Not Reactive by Default impact: HIGH impactDescription: Provided primitive values lose reactivity, causing injecting components to not update when the source value changes type: gotcha tags: [vue3, provide-inject, reactivity, composition-api, options-api] --- # Provide/Inject Values Are Not Reactive by Default **Impact: HIGH** - A common misconception is that provide/inject automatically maintains reactivity. By default, provided primitive values are NOT reactive. If the provided value changes in the provider, injecting components will NOT be updated. ## Task Checklist - [ ] Always wrap primitive values in `ref()` before providing - [ ] Use `computed()` in Options API `provide()` for reactive data - [ ] Never destructure refs when providing - pass the ref directly - [ ] Understand that provided refs are NOT auto-unwrapped in injectors ## The Gotcha: Primitives Lose Reactivity **Wrong - Primitive loses reactivity:** ```vue ``` ```vue ``` **Correct - Provide the ref itself:** ```vue ``` ```vue ``` ## Options API: Use computed() for Reactivity In Options API, the `provide` option with plain properties is NOT reactive: **Wrong - Options API without computed:** ```js export default { data() { return { message: 'Hello' } }, // WRONG: This is NOT reactive provide() { return { message: this.message // Provides 'Hello' as a static string } } } ``` **Correct - Use computed() in Options API:** ```js import { computed } from 'vue' export default { data() { return { message: 'Hello' } }, provide() { return { // CORRECT: Wrap in computed for reactivity message: computed(() => this.message) } } } ``` ## Understanding Ref Behavior in Inject When you provide a ref, it is injected as-is and NOT auto-unwrapped: ```vue ``` ```vue ``` ## Providing Reactive Objects Reactive objects (created with `reactive()`) maintain reactivity when provided: ```vue ``` ```vue ``` ## Common Mistake: Destructuring Breaks Reactivity **Wrong - Destructuring provided reactive state:** ```vue ``` **Correct - Keep the reference intact:** ```vue ``` ## Debugging Tip If your injected value isn't updating: 1. Check if you provided `ref.value` instead of `ref` 2. Check if you destructured a reactive object 3. In Options API, ensure you used `computed()` 4. Use Vue DevTools to inspect the provided values ## Reference - [Vue.js Provide/Inject - Working with Reactivity](https://vuejs.org/guide/components/provide-inject.html#working-with-reactivity) - [How to make provide/inject reactive - LogRocket Blog](https://blog.logrocket.com/how-to-make-provide-inject-reactive/) - [GitHub Issue: Inject/Provide is not reactive](https://github.com/vuejs/vue/issues/7017)