When Vue re-renders a single component, it can disrupt the rendering of other

I am faced with a dilemma involving two components that display varying information from the same data object stored in the state. Each component listens for store actions to detect changes and trigger a re-render.

It is worth noting that Component A is nested within Component B.

Component A

// Keeping track of changes; refs.example influences DOM elements
const refs: {
  example?: Exercise,
} = reactive({
  example: undefined,
})

// Subscribing to selected changes
store.subscribeAction({
  after: (action) => {
    if (!subscribedActions.includes(action.type)) return
    // Altering selected triggers reset of example and re-renders
    refs.example = store.getters['selected'] as Example
  },
})

Component B

// Similar to Component A

Whenever selected is modified by an action, both instances of refs.example are updated causing re-renders in both components. Notably, Component A re-renders before Component B.
However, once Component B completes its re-render process, Component A unexpectedly rerenders as if its refs.example became undefined. This occurs especially when there's a delay in setting refs.example in Component B using setTimeout. Interestingly, if Component A is postponed until after B has re-rendered, Component A fails to render properly.

If Component B follows Component A in terms of rendering sequence, there is a brief moment where both components render correctly. However, towards the end of this cycle,

Vue's source code

function flushJobs(seen) {
  isFlushPending = false;
  isFlushing = true;
  if ((process.env.NODE_ENV !== 'production')) {
      seen = seen || new Map();
  }
  flushPreFlushCbs(seen);
  // Sorting queue before flushing.
  // Ensures:
  // 1. Parent components update before children. (parents created first)
  // 2. Unmounted components updates can be skipped if parent is updating.
  queue.sort((a, b) => getId(a) - getId(b));
  // Conditional checkRecursiveUpdate usage determined outside try ... catch block due to optimization issues
  const check = (process.env.NODE_ENV !== 'production')
      ? (job) => checkRecursiveUpdates(seen, job)
      : NOOP;
  try {
      for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
          const job = queue[flushIndex];
          if (job && job.active !== false) {
              if ((process.env.NODE_ENV !== 'production') && check(job)) {
                  continue;
              }
              
              // COMPONENT A RENDERS AS UNDEFINED HERE
              callWithErrorHandling(job, null, 14 /* SCHEDULER */);
          }
      }
  }
...

Any thoughts on how to address this issue?

Answer №1

Although the cause of this issue remains unknown to me, I have discovered a solution for handling changes to a single object in store across two separate components: Utilize store getters and computed():

Component X

const data: {
  item?: Product,
} = reactive({
  item: computed(() => store.getters['products/selected'] as Product),
})

The aforementioned code can also be applied in Component Y. As an alternative approach, given that Y is a child component of X, X could delegate the data to Y.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I implement a feature in Angular where clicking the edit button loads a form (in a separate component) pre-populated with previous data, along with an update button for

Within the employee-list component, there is a table displaying a list of employees. This table includes an option to edit details. <button type="button" class="btn btn-primary" routerLink="../create-employee">Edit</b ...

Convert the encoding of the FileReader's output to UTF-8

I am currently working on a small function that is meant to fetch the contents of an uploaded text file. upload() { let reader = new FileReader(); reader.onload = () => { console.log(reader.result); } reader.readAsText(this.file ...

Coding with Angular 4 in JavaScript

Currently, I am utilizing Angular 4 within Visual Studio Code and am looking to incorporate a JavaScript function into my code. Within the home.component.html file: <html> <body> <button onclick="myFunction()">Click me</button> ...

Modify the "field" key type within the GridColDef interface of MUI DataGrid

Is there a way to assign an array of specific strings to the default type of GridColDef's field key, which is typically set to string? I attempted solutions like Array<Omit<GridColDef, 'field'> & {field: 'name' | &apo ...

Mechanism for Generating Names in TypeScript

We are in the process of reorganizing an older package. To do this, we have begun transitioning from the original "export = module" syntax to "export default module". However, this change is causing issues with another part of our code that utilizes eval() ...

AngularJS ui-router behaving erratically when manually refreshing the page

While working on an application with my team, we've noticed some inconsistent behavior. When a user refreshes the browser, the page UI state is fully refreshed, but only up to a certain route. Our application starts on the /Home route, establishing t ...

Performing Cypress testing involves comparing the token stored in the localStorage with the one saved in the clipboard

I am currently working on a button function that copies the token stored in localStorage to the clipboard. I am trying to write code that will compare the token in localStorage with the one in the clipboard in order to verify if the copy was successful. H ...

Combine a constant interface with a generic function to create a unique generic interface

When dealing with legacy code that utilizes a const in the following pattern: const fnUsedInSetPrototypeOf = { equalityComparer<T>(a: T, b: T) { return a === b }, otherFn<T> (this: T) { /*...*/ }, // ... other things, all along the ...

The Primevue Chart failed to display

I'm having some trouble displaying a Chart using Primevue components. It's built on the chart.js library. Currently, I have a basic Vue component set up as follows: <template> <div class="p-chart"> <h2>Chart:< ...

Drizzle ORM does not offer support for the Insert Returning feature

I am facing a query while utilizing Drizzle ORM with MySQL. At present, Drizzle ORM lacks an insert returning function for MySQL. Feel free to refer to this link for more information. My platform registers users into the system and generates JWT tokens u ...

Encounter the "Error: Source 'cloudsTileLayer-RasterSource' not found" message while trying to integrate a weather tile layer into Azure Maps

I have been working on a React application that utilizes the React-Azure-Maps npm package. My current challenge involves creating a weather layer, which I believe shares similarities with the sample code provided for layers. The code snippet responsible f ...

Issues with the transition-group feature during the upgrade from vuetify2 to vuetify3

Transitioning from Vue2 Vuetify2 to Vue3 Vuetify3 has proven to be quite a challenge. My code seems to require less reliance on Vuetify as certain components like v-treeview are not functioning properly and I've had to redo everything from scratch. C ...

TypeScript code to transform an array of strings into a custom object

I have a specific requirement that I have partially achieved using Java, but now I need to transition it to TypeScript on the client side. Please note: The input provided below is for illustrative purposes and may vary dynamically. Input: var input = [" ...

Access uninitialized properties in Typescript post-compilation

I am currently in the process of creating a wrapper for socket.io. Coming from a strong object-oriented background, I aim to incorporate the idea of Models into my framework/wrapper. For those familiar with socket.io, you may know that data associated wit ...

When using TypeScript, the reducer function may not be recognized, causing the type to display as 'any

I am a beginner in Typescript and we are implementing hooks in our React application. We have a shared thunk action creator that triggers one of the actions. appSlice.ts type ThunkOptions = { method: number, api_url: string, body: any | null } ...

In Typescript, how do we differentiate between an object and a string?

As I develop an Infrastructure-as-Code for a Step Functions Machine, one of the states is a 'Task' type that executes a DynamoUpdateItem on a DynamoDB table. The code snippet is as follows: const updateDDB = new tasks.DynamoUpdateItem(this, ...

Encountering a Syntaxerror While Working with Vue.js Router and Parameters

As a newcomer to Vue Js, here is a snippet from my routes code: import Vue from 'vue'; import Router from 'vue-router'; import dashboard from './views/dashboard.vue'; import settings from './views/settings.vue'; co ...

Step-by-step guide to generating an organizational chart with vue-google-charts

After following the instructions for using the vue-google-charts plugin here: https://www.npmjs.com/package/vue-google-charts, I wanted to create an organization chart as shown in the example provided by Google Charts here: https://developers.google.com/ch ...

Centering on request, Google Maps adjusts its view to focus on

When I select a row, I want to set the map center to the provided coordinates in Primeng. The issue is that while this.options works fine in ngOnInit, it doesn't work when called in the showCords() function. Below is my code: gmap.component.ts im ...

While developing an exam portal with Angular and Spring Boot, I encountered an issue when trying to incorporate a name field as [name]

Component.html <div class="bootstrap-wrapper" *ngIf="!isSubmit"> <div class="container-fluid"> <div class="row"> <div class="col-md-2"> <!- ...