Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

bwrigley's avatar

Reactivity loop

Still very new to Vue and understanding reactivity, but I seem to have got myself into a bit of a mess.

I have a simple composable that runs an algolia search everytime the user starts typing a hashtag in the parent component. It sends back it's results and, for now, I'm just dumping them to my screen so I can check the results. This is all working fine:

My composable:


import { ref, watchEffect } from 'vue';
import algoliasearch from 'algoliasearch/lite';

export function remoteSearch(indexName, attribute, query) {

  const results = ref([]);

  const searchClient = algoliasearch(
    import.meta.env.VITE_ALGOLIA_APP_ID,
    import.meta.env.VITE_ALGOLIA_SEARCH
  );

  const index = searchClient.initIndex(indexName);



  watchEffect(async() => {

    results.value = [];

    const res = await index.search(query.value);

    results.value = res.hits.map((hit) => hit[attribute]);



  });

  return(results);
}

And the component that triggers the search every time the user changes modelValue:

<script setup>

    import {computed} from 'vue';
    import {remoteSearch} from '@/composables/remoteSearch.js';
    import FormSelect from './FormSelect.vue';

    const props = defineProps({
        modelValue : {
            type: [String, null],
            required: true
        },
        index : {
            type: String,
            required : true
        },
        attribute : {
            type: String,
            required : true
        }
    })

    const text = computed(() => {
        return props.modelValue ?? '';
    });

    const query = computed(() => {
        const regex = /#(\w+)$/;
        const match = text.value.match(regex);
        return match ? match[1] : null
    });

    const results = computed(() => {

        return  remoteSearch(props.index,props.attribute,query);

    });





</script>
<template>

    <slot></slot>

    <!-- <FormSelect :items="results"/> -->

    {{ results }}



</template>

The problem is that results is an array, and I want to convert it to an object where the array values should be both key and value.

so I changed the results computation in my component to:

    const results = computed(() => {

        const res = remoteSearch(props.index,props.attribute,query);

        return Object.assign({},res.value);

    });

which just killed the client because of what I suspect is a reactivity loop.

Can anyone suggest how to do this?

0 likes
0 replies

Please or to participate in this conversation.