Is what you write exactly composable?

Hello! In this article, using a simple checklist in a couple of steps, we will find out whether the functions you write in your Vue code are truly composable.

According to documentationcomposables are functions that, thanks to their use within themselves, composition APIencapsulate and reuse logic that involves application state (local or global).

If your function takes certain numbers as input and returns the smallest value of them, then such a function does not work with state, which means it cannot be called composable, in fact it is a utility function.

function minValue(...args) {
    const min = args.reduce((acc, val) => {
        return acc < val ? acc : val;
    });
    return min;
}

On the other hand, if your function manipulates state (be it internal or global state), performs external interactions to fill that state (fetching, Intersection Observer, DOM manipulation), then it is certainly truly composable and its name follows start from use

function useMenu(gqlClient: GqlClient) {
    const isLoading = ref(false);
    const menuItems = ref<MenuSectionItem[]>([]);

    function setSectionItem(item: Section): SectionItem {...}

    async function fetchMenuItemList() {
      const result = await gqlClient.query(getMenuQuery());
      ...
      menuItems.value = result.items;
    }
}

✏️ Checklist for determining Vue composable

Just one hit on the point will be enough to pass the test, you no need to hit all three.

  1. Your function internally uses lifecycle methods.

function useInterval(cb: () => void, interval = 1000) {
  let timer: ReturnType<typeof setInterval> | null = null

  function clean() {
    if (timer) {
      clearInterval(timer)
      timer = null
    }
  }

  onMounted(() => {
    if (interval <= 0) return;
  
    timer = setInterval(cb, interval)
  })
  
  onBeforeUnmount(() => {
    clean()
  })
}

The function above does not manipulate state, but is still composable because it uses the component's lifecycle methods. It satisfies the first point.

  1. Your function internally uses other composables. Of course, you can very well build a composition of composable functions, and if the only job of a function is to call another composable function internally, then it is also composable, without exception. For example, a function can internally use something you wrote useFetch use useSomething from the library vue-use etc.

function useScreenInitialize() {
    const { x, y } = useMouse()
    // возможна дополнительная логика
    return [x, y]
}
  1. Your function has stateful logic. Most often this is working with refwhich stores a certain state, and changing or transforming this state occurs in a function.

function useUser (gqlClient: GqlClient) {
  const user = ref(null)
  const userPreferences = computed(() => user.value?.preferences ?? [])

  async function fetchUser () {
    user.value = await gqlClient.query(getUserQuery())
  }
  // больше логики опционально

  return {
    user: readonly(user),
    fetchUser,
    userPreferences
  }
}

Bottom line

Composables are functions in the composition API that reuse logic with lifecycle methods, other composables, and/or store and transform state.

✌️ Always happy for suggestions and feedback – bronnikovmb@gmail.com

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *