Skip to content

Commit 6b6b3f4

Browse files
authored
Merge pull request #7448 from QwikDev/v2-vnode-refs
fix: don't execute QRLs for elements marked as deleted
2 parents 24d9a2d + 6e29af3 commit 6b6b3f4

File tree

12 files changed

+261
-239
lines changed

12 files changed

+261
-239
lines changed

.changeset/strange-bottles-sleep.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/core': patch
3+
---
4+
5+
fix: don't execute QRLs for elements marked as deleted

packages/qwik/src/core/client/dom-container.ts

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,25 +83,6 @@ export function getDomContainerFromQContainerElement(qContainerElement: Element)
8383
let container = qElement.qContainer;
8484
if (!container) {
8585
container = new DomContainer(qElement);
86-
87-
const containerAttributes: Record<string, string> = {};
88-
if (qElement) {
89-
const attrs = qElement.attributes;
90-
if (attrs) {
91-
for (let index = 0; index < attrs.length; index++) {
92-
const attr = attrs[index];
93-
if (attr.name === Q_PROPS_SEPARATOR) {
94-
continue;
95-
}
96-
containerAttributes[attr.name] = attr.value;
97-
}
98-
}
99-
}
100-
(container as DomContainer).$serverData$ = { containerAttributes };
101-
102-
qElement.setAttribute(QContainerAttr, QContainerValue.RESUMED);
103-
104-
qElement.qContainer = container;
10586
}
10687
return container;
10788
}
@@ -163,22 +144,23 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
163144
this.$instanceHash$ = element.getAttribute(QInstanceAttr)!;
164145
this.qManifestHash = element.getAttribute(QManifestHashAttr)!;
165146
this.rootVNode = vnode_newUnMaterializedElement(this.element);
166-
// These are here to initialize all properties at once for single class transition
167-
this.$rawStateData$ = null!;
168-
this.$stateData$ = null!;
147+
this.$rawStateData$ = [];
148+
this.$stateData$ = [];
169149
const document = this.element.ownerDocument as QDocument;
170150
if (!document.qVNodeData) {
171151
processVNodeData(document);
172152
}
173-
this.$rawStateData$ = [];
174-
this.$stateData$ = [];
153+
this.$qFuncs$ = getQFuncs(document, this.$instanceHash$) || EMPTY_ARRAY;
154+
this.$setServerData$();
155+
element.setAttribute(QContainerAttr, QContainerValue.RESUMED);
156+
element.qContainer = this;
157+
175158
const qwikStates = element.querySelectorAll('script[type="qwik/state"]');
176159
if (qwikStates.length !== 0) {
177160
const lastState = qwikStates[qwikStates.length - 1];
178161
this.$rawStateData$ = JSON.parse(lastState.textContent!);
179162
this.$stateData$ = wrapDeserializerProxy(this, this.$rawStateData$) as unknown[];
180163
}
181-
this.$qFuncs$ = getQFuncs(document, this.$instanceHash$) || EMPTY_ARRAY;
182164
}
183165

184166
$setRawState$(id: number, vParent: ElementVNode | VirtualVNode): void {
@@ -372,4 +354,21 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
372354
this.$journal$.push(VNodeJournalOpCode.Insert, this.document.head, null, styleElement);
373355
}
374356
}
357+
358+
// TODO: should be moved to the Qwik Router?
359+
/** Set the server data for the Qwik Router. */
360+
private $setServerData$(): void {
361+
const containerAttributes: Record<string, string> = {};
362+
const attrs = this.element.attributes;
363+
if (attrs) {
364+
for (let index = 0; index < attrs.length; index++) {
365+
const attr = attrs[index];
366+
if (attr.name === Q_PROPS_SEPARATOR) {
367+
continue;
368+
}
369+
containerAttributes[attr.name] = attr.value;
370+
}
371+
}
372+
this.$serverData$ = { containerAttributes };
373+
}
375374
}

packages/qwik/src/core/client/queue-qrl.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import type { QRLInternal } from '../shared/qrl/qrl-class';
33
import { ChoreType } from '../shared/util-chore-type';
44
import { getInvokeContext } from '../use/use-core';
55
import { useLexicalScope } from '../use/use-lexical-scope.public';
6-
import { _getQContainerElement, getDomContainer } from './dom-container';
7-
import type { ElementVNode } from './types';
6+
import { getDomContainer } from './dom-container';
87

98
/**
109
* This is called by qwik-loader to schedule a QRL. It has to be synchronous.
@@ -15,8 +14,14 @@ export const queueQRL = (...args: unknown[]) => {
1514
// This will already check container
1615
const [runQrl] = useLexicalScope<[QRLInternal<(...args: unknown[]) => unknown>]>();
1716
const context = getInvokeContext();
18-
const hostElement = context.$hostElement$ as ElementVNode;
19-
const container = getDomContainer(hostElement);
17+
const hostElement = context.$hostElement$;
18+
19+
if (!hostElement) {
20+
// silently ignore if there is no host element, the element might have been removed
21+
return;
22+
}
23+
24+
const container = getDomContainer(context.$element$!);
2025

2126
const scheduler = container.$scheduler$;
2227
if (!scheduler) {

packages/qwik/src/core/client/vnode-diff.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import type { HostElement, QElement, QwikLoaderEventScope, qWindow } from '../sh
4646
import { DEBUG_TYPE, QContainerValue, VirtualType } from '../shared/types';
4747
import type { DomContainer } from './dom-container';
4848
import {
49+
ElementVNodeProps,
4950
VNodeFlags,
5051
VNodeProps,
5152
type ClientAttrKey,
@@ -739,11 +740,14 @@ export const vnode_diff = (
739740
mapArray_set(jsxAttrs, ELEMENT_KEY, jsxKey, 0);
740741
}
741742
const vNode = (vNewNode || vCurrent) as ElementVNode;
743+
744+
const element = vNode[ElementVNodeProps.element] as QElement;
745+
element.vNode = new WeakRef(vNode);
746+
742747
needsQDispatchEventPatch =
743748
setBulkProps(vNode, jsxAttrs, currentFile) || needsQDispatchEventPatch;
744749
if (needsQDispatchEventPatch) {
745750
// Event handler needs to be patched onto the element.
746-
const element = vnode_getNode(vNode) as QElement;
747751
if (!element.qDispatchEvent) {
748752
element.qDispatchEvent = (event: Event, scope: QwikLoaderEventScope) => {
749753
const eventName = event.type;

0 commit comments

Comments
 (0)