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?