Ref vs. Reactive

Is it better to use ref or reactive when using the Composition API?

Here are a few situations where ref is better than reactive.

Using ref on objects makes it clear where an object is reactive and where it's just a plain object:

// I can expect this ref to update reactively
if (burger.value.lettuce) {
// ...
}
// I have no clue if this value is reactive
if (burger.lettuce) {
// ...
}

When using one of the watch methods, refs are automatically unwrapped, so they're nicer to use:

// Ref
const refBurger = ref({ lettuce: true });
watch(
// Not much, but it's a bit simpler to work with
refBurger,
() => console.log("The burger has changed"),
{ deep: true }
);
// Reactive
const reactiveBurger = reactive({ lettuce: true });
watch(
reactiveBurger,
() => console.log("The burger has changed"),
);

One last reason why refs make more sense to me — you can put refs into a reactive object. This lets you compose reactive objects out of refs and still use the underlying refs directly:

const lettuce = ref(true);
const burger = reactive({
// The ref becomes a property of the reactive object
lettuce,
});
// We can watch the reactive object
watchEffect(() => console.log(burger.lettuce));
// We can also watch the ref directly
watch(lettuce, () => console.log("lettuce has changed"));
setTimeout(() => {
// Updating the ref directly will trigger both watchers
// This will log: `false`, 'lettuce has changed'
lettuce.value = false;
}, 500);

I wrote a very comprehensive article comparing the two even further if you want to go deeper.