Skip to content

Commit 13fec50

Browse files
committed
fix: reexecute component with null key
1 parent f3ae77d commit 13fec50

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

.changeset/dirty-lemons-shop.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: reexecute component with null key

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ export const vnode_diff = (
10431043
}
10441044
host = vNewNode as VirtualVNode;
10451045
shouldRender = true;
1046-
} else if (!hashesAreEqual) {
1046+
} else if (!hashesAreEqual || !jsxNode.key) {
10471047
insertNewComponent(host, componentQRL, jsxProps);
10481048
host = vNewNode as VirtualVNode;
10491049
shouldRender = true;

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,55 @@ describe.each([
19911991
);
19921992
});
19931993

1994+
it('should reexecute entire component without key', async () => {
1995+
const Child = component$((props: { text: string }) => {
1996+
const text = useSignal('');
1997+
useTask$(() => {
1998+
text.value = props.text;
1999+
});
2000+
return <div>{text.value}</div>;
2001+
});
2002+
2003+
const Cmp = component$(() => {
2004+
const toggle = useSignal(true);
2005+
2006+
return (
2007+
<>
2008+
<button onClick$={() => (toggle.value = !toggle.value)}></button>
2009+
{/* no key for both components */}
2010+
{toggle.value ? jsx(Child, { text: 'Hello' }, null) : jsx(Child, { text: 'World' }, null)}
2011+
</>
2012+
);
2013+
});
2014+
2015+
const { vNode, document } = await render(<Cmp />, { debug });
2016+
expect(vNode).toMatchVDOM(
2017+
<Component ssr-required>
2018+
<Fragment ssr-required>
2019+
<button></button>
2020+
<Component ssr-required>
2021+
<div>
2022+
<Signal ssr-required>Hello</Signal>
2023+
</div>
2024+
</Component>
2025+
</Fragment>
2026+
</Component>
2027+
);
2028+
await trigger(document.body, 'button', 'click');
2029+
expect(vNode).toMatchVDOM(
2030+
<Component ssr-required>
2031+
<Fragment ssr-required>
2032+
<button></button>
2033+
<Component ssr-required>
2034+
<div>
2035+
<Signal ssr-required>World</Signal>
2036+
</div>
2037+
</Component>
2038+
</Fragment>
2039+
</Component>
2040+
);
2041+
});
2042+
19942043
describe('regression', () => {
19952044
it('#3643', async () => {
19962045
const Issue3643 = component$(() => {

packages/qwik/src/core/tests/use-on.spec.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ import {
1414
useTask$,
1515
useVisibleTask$,
1616
} from '@qwik.dev/core';
17-
import { domRender, ssrRenderToDom } from '@qwik.dev/core/testing';
17+
import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing';
1818
import { describe, expect, it } from 'vitest';
19-
import { trigger } from '../../testing/element-fixture';
2019

2120
const debug = false; //true;
2221
Error.stackTraceLimit = 100;

0 commit comments

Comments
 (0)