Porque reactive() usa un Proxy para registrar el acceso a propiedades. Al desestructurar, extraes valores planos fuera del proxy y la conexión reactiva desaparece.
ts
const state = reactive({ count: 0, name: 'Vue' })
const { count, name } = state // count ahora es solo el número 0
state.count++
console.log(count) // sigue siendo 0, se perdió la reactividadEsto es especialmente peligroso al desestructurar el valor de retorno de un composable:
ts
function useCounter() {
const state = reactive({ count: 0 })
return state
}
const { count } = useCounter() // número plano, no reactivoCómo solucionarlo
Opción 1: Usar toRefs para convertir cada propiedad en un ref antes de desestructurar.
ts
const state = reactive({ count: 0, name: 'Vue' })
const { count, name } = toRefs(state)
state.count++
console.log(count.value) // 1, reactividad conservada (ahora necesita .value)Opción 2: Devolver toRefs() desde los composables para que los consumidores puedan desestructurar sin problemas.
ts
function useCounter() {
const state = reactive({ count: 0 })
return toRefs(state)
}
const { count } = useCounter() // ref, reactividad conservadaOpción 3: Prescindir de reactive() y usar ref() para cada valor.
ts
const count = ref(0)
const name = ref('Vue')
// No hace falta desestructurar, sin problemasLa mayoría de los equipos usan ref() para todo precisamente para evitar este problema.
Ver también: ¿Cómo funcionan toRefs, toRef y toValue? · ¿Por qué reactive() no funciona con primitivos?