# provide and inject — Vue.js

Source: https://www.skillbyai.com/en/vue/p-provide

> Passing data deep without prop drilling.

## Dependency injection for component trees

Passing a prop through many intermediate components that do not use it is called **prop drilling**. With `provide(key, value)` an ancestor makes a value available to all its descendants, and any descendant reads it with `inject(key, defaultValue)`. Providing a ref keeps the link reactive. A good practice is to keep mutations in the provider by also providing an update function, and to wrap values with `readonly()` when consumers should not change them. With TypeScript, an `InjectionKey` symbol gives the injected value a type. `app.provide` makes a value available to the whole app, which is how many plugins work.

## Providing a theme

An ancestor provides; a deep child injects.

```vue
<!-- App.vue -->
<script setup>
import { ref, provide, readonly } from 'vue'

const theme = ref('light')
function toggleTheme() {
  theme.value = theme.value === 'light' ? 'dark' : 'light'
}
provide('theme', { theme: readonly(theme), toggleTheme })
</script>

<!-- ThemeButton.vue, anywhere below App -->
<script setup>
import { inject } from 'vue'

const { theme, toggleTheme } = inject('theme', {
  theme: 'light',
  toggleTheme: () => {},
})
</script>

<template>
  <button @click="toggleTheme">Theme: {{ theme }}</button>
</template>
```

## Building-wide Wi-Fi

Instead of running a cable through every room (props), the building broadcasts a network (provide) and any device on any floor can connect (inject).

**Quiz:** What problem does provide/inject mainly solve?

- [ ] Fetching data from a server
- [x] Prop drilling through components that do not need the data
- [ ] Styling child components
- [ ] Routing between pages

*Answer:* Prop drilling through components that do not need the data. Ancestors share values with any descendant.
