Skip to content

Commit

Permalink
fix(render): fix component rendering (#6984)
Browse files Browse the repository at this point in the history
* fix component rendering

* revert doc search key changes
  • Loading branch information
Varixo authored Oct 16, 2024
1 parent 75fd3bc commit c97cb71
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 2 deletions.
3 changes: 1 addition & 2 deletions packages/docs/src/components/docsearch/results-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ export const ResultsScreen = component$((props: { state: DocSearchState }) => {
<ul role="listbox" aria-labelledby="docsearch-label" id="docsearch-list">
{collection.items.map((item, index) => {
return (
// TODO: the key should be {item.objectID}, but for now in v2 there is a bug
<Result state={props.state} item={item} key={item.__autocomplete_id}>
<Result state={props.state} item={item} key={item.objectID}>
{item.__docsearch_parent && (
<svg q:slot="start-action" class="DocSearch-Hit-Tree" viewBox="0 0 24 54">
<g
Expand Down
6 changes: 6 additions & 0 deletions packages/qwik/src/core/client/vnode-diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,12 @@ export const vnode_diff = (
const vNodeProps = vnode_getProp<any>(host, ELEMENT_PROPS, container.$getObjectById$);
shouldRender = shouldRender || propsDiffer(jsxProps, vNodeProps);
if (shouldRender) {
/**
* Mark host as not deleted. The host could have been marked as deleted if it there was a
* cleanup run. Now we found it and want to reuse it, so we need to mark it as not
* deleted.
*/
host[VNodeProps.flags] &= ~VNodeFlags.Deleted;
container.$scheduler$(ChoreType.COMPONENT, host, componentQRL, jsxProps);
}
}
Expand Down
143 changes: 143 additions & 0 deletions packages/qwik/src/core/tests/component.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Fragment as Component,
Fragment,
Fragment as InlineComponent,
Fragment as Projection,
SSRComment,
Fragment as Signal,
SkipRender,
Expand All @@ -16,6 +17,7 @@ import {
type JSXOutput,
useTask$,
type Signal as SignalType,
Slot,
} from '@builder.io/qwik';
import { domRender, ssrRenderToDom, trigger } from '@builder.io/qwik/testing';
import { describe, expect, it } from 'vitest';
Expand Down Expand Up @@ -1774,6 +1776,147 @@ describe.each([
);
});

it('should rerender components with projection and condition after sort', async () => {
interface Item {
id: string;
level: number;
value: {
title: string;
};
}

const SecondChild = component$((props: any) => {
return props.title + props.index;
});

const FirstChild = component$<{ item: Item; index: number }>((props) => {
return (
<div>
<Slot />
{props.item.level === 1 && (
<SecondChild title={props.item.value.title} index={props.index} />
)}
</div>
);
});

const Parent = component$(() => {
const data = useStore<{ items: Item[] }>({
items: [
{
id: 'foo',
level: 1,
value: {
title: 'qwik 1',
},
},
{
id: 'aaa',
level: 2,
value: {
title: 'qwik 2',
},
},
{
id: 'bar',
level: 1,
value: {
title: 'qwik 3',
},
},
],
});

return (
<div>
<button
onClick$={() => {
data.items.sort((a, b) => a.id.localeCompare(b.id));
}}
></button>
<section>
{data.items.map((item, index) => {
return (
<FirstChild key={item.id} item={item} index={index}>
<span>{index}</span>
</FirstChild>
);
})}
</section>
</div>
);
});

const { vNode, document } = await render(<Parent />, { debug });
expect(vNode).toMatchVDOM(
<Component>
<div>
<button></button>
<section>
<Component>
<div>
<Projection>
<span>0</span>
</Projection>
<Component>qwik 10</Component>
</div>
</Component>
<Component>
<div>
<Projection>
<span>1</span>
</Projection>
{''}
</div>
</Component>
<Component>
<div>
<Projection>
<span>2</span>
</Projection>
<Component>qwik 32</Component>
</div>
</Component>
</section>
</div>
</Component>
);
await trigger(document.body, 'button', 'click');
expect(vNode).toMatchVDOM(
<Component>
<div>
<button></button>
<section>
<Component>
<div>
<Projection>
<span>0</span>
</Projection>
{''}
</div>
</Component>
<Component>
<div>
<Projection>
<span>1</span>
</Projection>
<Component>qwik 31</Component>
</div>
</Component>
<Component>
<div>
<Projection>
<span>2</span>
</Projection>
<Component>qwik 12</Component>
</div>
</Component>
</section>
</div>
</Component>
);
});

describe('regression', () => {
it('#3643', async () => {
const Issue3643 = component$(() => {
Expand Down

0 comments on commit c97cb71

Please sign in to comment.