I'm starting to get comfortable with Vue's composition API, but every time I make a composable I ask myself which pattern to use. If I have a composable whose state depends on outside triggers:
- should I return a function from the composable that performs an action on the state? Or
- should I instead let the composable accept a reactive state from outside to update the state managed by the composable?
Scenario: list users
For example, I need to make a composable that fetches a list of users from an API. The list must reactively update when filtered by user name.
Composable pattern 1: return reactive list and action on that list
<script setup lang="ts">
const { list, setList } = useUserList();
</script>
<template>
<pre>{{ list }}</pre>
<button type="button" @click="setList('john')">List users named "John"</button>
</template>
Composable pattern 2: return reactive list based on input reactive dependency
<script setup lang="ts">
const nameFilter = ref('');
const { list } = useUserList(nameFilter);
</script>
<template>
<pre>{{ list }}</pre>
<button type="button" @click="nameFilter = 'John'">List users named "John"</button>
</template>
Which of the two patterns should I do? The example scenario may be simple enough to make the choice negligible, but on more complex logic (e.g., making higher-order composables) I imagine its effect compounding.
nameFilterbecomes extensive, using Composable Pattern 1 would lead to overly bloated code, in which case I would opt for Composable Pattern 2 or other patterns.nameFilterref in pattern 1 then callsetList(nameFilter.value)every time the ref value changes.