primevue icon indicating copy to clipboard operation
primevue copied to clipboard

AccordionTab: does not re-render when reactive variable change, sometimes is not rendered at all

Open K4T opened this issue 1 year ago • 4 comments

Describe the bug

I have created a simple carousel, and in each carousel item, I need to display different, dynamic Accordions/AccordionTabs. The problem is that accordions are not re-rendered after I switch slides (update reactive variable responsible for keeping value of currently displayed object in slide). Accordions are correctly rendered only on page load, but they are not updated after a slide change view pressing Next or Prev buttons. I have also noticed that sometimes accordions are not rendered at all...

Can be related to: https://github.com/primefaces/primevue/issues/622

Reproducer

https://stackblitz.com/edit/u1x8yw-tyjpd3?file=src%2FApp.vue

PrimeVue version

3.37.0

Vue version

3.x

Language

ES6

Build / Runtime

Vite

Browser(s)

No response

Steps to reproduce the behavior

  1. Open attached demo
  2. First slide will be rendered on page load with correct data and content (also for accordions)
  3. Click "next" to change the slide - accordion tabs are not being updated

Expected behavior

Accordion tabs should re-render with new content (book).

K4T avatar Oct 19 '23 20:10 K4T

We've run into this as well. The Accordion component won't re-render on data updates. The inputs within the Accordion remain reactive, but the component just won't re-render.

We found this solution (hack), based on this article: https://michaelnthiessen.com/force-re-render/#key-changing-to-force-a-component-refresh

Wrote a composable for our Nuxt project (useRenderKey.ts):

import { ref } from 'vue';
// "generateId" generates a random alphanumeric string from our utilities
const { generateId } = useUtilities();
const renderKey = ref(generateId());
function updateRenderKey() {
  renderKey.value = generateId();
}

export default function () {
  return {
    renderKey,
    updateRenderKey
  };
}

Then, in the component:

<script setup>
import { computed } from 'vue';
const { renderKey, updateRenderKey } = useRenderKey();
const panelData = computed(() => {
  // do stuff that generates the AccordionTab's UI data...
  updateRenderKey();
  return ...
});
</script>

<template>
// template stuff here...
<Accordion :key="renderKey">...</Accordion>
// more template stuff...
</template>

danluchs avatar Nov 09 '23 16:11 danluchs

Describe the bug

I have created a simple carousel, and in each carousel item, I need to display different, dynamic Accordions/AccordionTabs. The problem is that accordions are not re-rendered after I switch slides (update reactive variable responsible for keeping value of currently displayed object in slide). Accordions are correctly rendered only on page load, but they are not updated after a slide change view pressing Next or Prev buttons. I have also noticed that sometimes accordions are not rendered at all...

Can be related to: #622

Reproducer

https://stackblitz.com/edit/u1x8yw-tyjpd3?file=src%2FApp.vue

PrimeVue version

3.37.0

Vue version

3.x

Language

ES6

Build / Runtime

Vite

Browser(s)

No response

Steps to reproduce the behavior

  1. Open attached demo
  2. First slide will be rendered on page load with correct data and content (also for accordions)
  3. Click "next" to change the slide - accordion tabs are not being updated

Expected behavior

Accordion tabs should re-render with new content (book).

Reproducer link seems working correctly. Am I missing something?

tugcekucukoglu avatar Nov 30 '23 12:11 tugcekucukoglu

Hello @tugcekucukoglu I encountered a similar issue and spent a day grappling with it before realizing that the AccordionTab wasn't updating.

Interestingly, I was able to reproduce the problem when using a computed property, but it appears that the computed property is not the root cause (as demonstrated in the StackBlitz example).

While it may seem unusual to use a computed property instead of a ref directly, this is a specific use case in our project. Occasionally, a sibling component initiates a change, which in turn triggers alterations in the computed properties within the page.

However, it seems that the issue arises when a function modifies the value of the variable used in v-for.

This example demonstrates the bug: https://stackblitz.com/edit/u1x8yw-xklxes?file=src%2FApp.vue

Right now, the only workaround is using the ref key to force re-render.

fernandoanael avatar Feb 07 '24 00:02 fernandoanael

I am also experiencing this. You can actually get the above reproduction failing as he expects it to by removing the key from the accordion element, and setting the initial currentItem in the carousel to the first index of the prop array to start. Even with just the key removed, the accordion tabs don't even show up. I think it has to do with the accordion tracking the ref of the set key. Taking it off makes it not track the changes made to the ref

JJosephttg avatar Apr 28 '24 20:04 JJosephttg

Experienced same thig, was struggling with content not updated 2 days, until made an experiment placing same output before and inside Accordiron: image

andrejko avatar Jun 07 '24 10:06 andrejko