Skip to content

Commit b50948d

Browse files
authored
Merge pull request #7365 from QwikDev/v2-inline-cmp-same-key
fix: replace inline component with component$ with the same key
2 parents aea1db3 + 513c9ab commit b50948d

File tree

3 files changed

+86
-4
lines changed

3 files changed

+86
-4
lines changed

.changeset/mean-parents-buy.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: replace inline component with component$ with the same key

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,10 +1079,8 @@ export const vnode_diff = (
10791079
shouldRender = true;
10801080
} else if (!hashesAreEqual) {
10811081
insertNewComponent(host, componentQRL, jsxProps);
1082-
if (vNewNode) {
1083-
host = vNewNode as VirtualVNode;
1084-
shouldRender = true;
1085-
}
1082+
host = vNewNode as VirtualVNode;
1083+
shouldRender = true;
10861084
}
10871085

10881086
if (host) {
@@ -1103,6 +1101,7 @@ export const vnode_diff = (
11031101
const lookupKey = jsxNode.key;
11041102
const vNodeLookupKey = getKey(host);
11051103
const lookupKeysAreEqual = lookupKey === vNodeLookupKey;
1104+
const vNodeComponentHash = getComponentHash(host, container.$getObjectById$);
11061105

11071106
if (!lookupKeysAreEqual) {
11081107
// See if we already have this inline component later on.
@@ -1116,6 +1115,11 @@ export const vnode_diff = (
11161115
}
11171116
host = vNewNode as VirtualVNode;
11181117
}
1118+
// inline components don't have component hash - q:renderFn prop, so it should be null
1119+
else if (vNodeComponentHash != null) {
1120+
insertNewInlineComponent();
1121+
host = vNewNode as VirtualVNode;
1122+
}
11191123

11201124
if (host) {
11211125
let componentHost: VNode | null = host;

packages/qwik/src/core/tests/inline-component.spec.tsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ const InlineWrapper = () => {
3636

3737
const Id = (props: any) => <div>Id: {props.id}</div>;
3838

39+
const ChildInline = () => {
40+
return <div>Child inline</div>;
41+
};
42+
3943
describe.each([
4044
{ render: ssrRenderToDom }, //
4145
{ render: domRender }, //
@@ -631,4 +635,73 @@ describe.each([
631635
</InlineComponent>
632636
);
633637
});
638+
639+
it('should render swap component$ and inline component with the same key', async () => {
640+
const Child = component$(() => {
641+
return <div>Child component$</div>;
642+
});
643+
644+
const Parent = component$(() => {
645+
const toggle = useSignal(true);
646+
return (
647+
<>
648+
<button onClick$={() => (toggle.value = !toggle.value)}></button>
649+
{/* same key, simulate different routes and files, but the same keys at the same place */}
650+
{toggle.value ? <ChildInline key="samekey" /> : <Child key="samekey" />}
651+
</>
652+
);
653+
});
654+
655+
const { vNode, document } = await render(<Parent />, { debug });
656+
657+
expect(vNode).toMatchVDOM(
658+
<Component ssr-required>
659+
<Fragment ssr-required>
660+
<button></button>
661+
<InlineComponent ssr-required>
662+
<div>Child inline</div>
663+
</InlineComponent>
664+
</Fragment>
665+
</Component>
666+
);
667+
668+
await trigger(document.body, 'button', 'click');
669+
670+
expect(vNode).toMatchVDOM(
671+
<Component ssr-required>
672+
<Fragment ssr-required>
673+
<button></button>
674+
<Component ssr-required>
675+
<div>Child component$</div>
676+
</Component>
677+
</Fragment>
678+
</Component>
679+
);
680+
681+
await trigger(document.body, 'button', 'click');
682+
683+
expect(vNode).toMatchVDOM(
684+
<Component ssr-required>
685+
<Fragment ssr-required>
686+
<button></button>
687+
<InlineComponent ssr-required>
688+
<div>Child inline</div>
689+
</InlineComponent>
690+
</Fragment>
691+
</Component>
692+
);
693+
694+
await trigger(document.body, 'button', 'click');
695+
696+
expect(vNode).toMatchVDOM(
697+
<Component ssr-required>
698+
<Fragment ssr-required>
699+
<button></button>
700+
<Component ssr-required>
701+
<div>Child component$</div>
702+
</Component>
703+
</Fragment>
704+
</Component>
705+
);
706+
});
634707
});

0 commit comments

Comments
 (0)