Flexible Arguments in Vue 3 composable functions

With Vue 3's isRef and unref functions, you can create flexible arguments with reactive or non-reactive values, making your code more reusable and versatile.


Continuing with the composable pattern, one improvement we can add is to allow the arguments to be flexible, meaning they can be reactive or non-reactive values. This makes your composable even more reusable.

How to achieve this? Thanks to the functions ref, unref, and isRef.

ref

Vue 3 reactivty API allows you to create reactive values either inside or outside a component (in a composable, for instance). When creating a reactive reference with ref, it returns an object with the original value stored in the value property, which is always up to date. For example:

JS
const name = ref("Juan")
name.value // Juan
name.value += " Andrés"
name.value // Juan Andrés

unref

This function returns the internal value stored in value if a reactive reference is passed to it. Otherwise (if it's not a reactive reference), it returns the argument as is.

JS
const name = ref("Juan")
const myName = unref(name) // retorna name.value
myName // Juan
const newName = unref(myName)
newName // Juan

isRef

Another useful utility is the isRef function, which returns a boolean value indicating whether a value is a reactive reference or not.

JS
const name = ref("Juan")
isRef(name) // true

Understanding this, how do we apply it to a composable?

Making useAsync Flexible

Let's enable our useAsync composable to accept an API_URL that can be either a static (string) or a reactive reference. The advantage of the second option is that we can react to changes in its value.

Below, I will embed the code for you to test, but essentially there are two important changes.

Firstly, we use unref to make the HTTP request to fetch the data. This way, we obtain the string with the URL, whether it's a reactive reference or not.

JS
const { results: users } = await (await fetch(unref(API_URL))).json();

The second change involves using isRef to determine if we can observe changes in API_URL and then retrigger the request using makeRequest.

JS
if (isRef(API_URL)) {
  watchEffect(makeRequest);
} else {
  makeRequest();
}

Now, you can change the URL to query and observe how the results are updated:

JS
setInterval(() => {
  const randomNumber = Math.floor(Math.random() * 10) + 1;
  API_URL.value = 'https://randomuser.me/api/?results=' + randomNumber;
}, 2000);

Conclusion

Use isRef and unref to create reusable code (not just composables) that can work with reactive values (created with ref) or static values (strings, numbers, etc).

Demo

Juan Andrés Núñez
Juan Andrés Núñez
Frontend Engineer. Vue.js Specialist. Professional Teacher. Stoic.