Skip to content

Commit

Permalink
fix: ensure components always return an object (#12290)
Browse files Browse the repository at this point in the history
Closes #12287

---------

Co-authored-by: Simon H <[email protected]>
Co-authored-by: Simon Holthausen <[email protected]>
  • Loading branch information
3 people authored Jul 4, 2024
1 parent 831552f commit e42bb61
Show file tree
Hide file tree
Showing 15 changed files with 74 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/warm-waves-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: ensure component always returns an object
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,9 @@ export function client_component(source, analysis, options) {
? b.return(b.call('$.pop', b.object(component_returned_object)))
: b.stmt(b.call('$.pop'))
);
} else {
// Always return an object, so that `bind:this` on this component will not be falsy
component_block.body.push(b.return(b.object(component_returned_object)));
}

if (analysis.uses_rest_props) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
export const a = {};
</script>

<div>a</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div>b</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
html: `<button>a</button><button>b</button><div>a</div>`,
compileOptions: {
dev: false
},

async test({ assert, target, logs, ok }) {
const [btn1, btn2] = target.querySelectorAll('button');

flushSync(() => {
btn2.click();
});

assert.htmlEqual(target.innerHTML, `<button>a</button><button>b</button><div>b</div>`);

flushSync(() => {
btn1.click();
});

assert.htmlEqual(target.innerHTML, `<button>a</button><button>b</button><div>a</div>`);
assert.deepEqual(logs, [{ a: {} }, {}, { a: {} }]);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script>
import ComponentA from './ComponentA.svelte';
import ComponentB from './ComponentB.svelte';
let type = $state(ComponentA);
let elem = $state.frozen();
$effect(() => {
console.log(elem);
});
</script>

<button
onclick={() => {
type = ComponentA;
}}>a</button
>
<button
onclick={() => {
type = ComponentB;
}}>b</button
>

<svelte:component this={type} bind:this={elem}>Content</svelte:component>
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ export default function Bind_component_snippet($$anchor) {

$.template_effect(() => $.set_text(text, ` value: ${$.get(value) ?? ""}`));
$.append($$anchor, fragment_1);
return {};
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ import * as $ from "svelte/internal/client";

export default function Bind_this($$anchor) {
$.bind_this(Foo($$anchor, { $$legacy: true }), ($$value) => foo = $$value, () => foo);
return {};
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ export default function Main($$anchor) {
});

$.append($$anchor, fragment);
return {};
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ export default function Each_string_template($$anchor) {
});

$.append($$anchor, fragment);
return {};
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ export default function Function_prop_no_getter($$anchor) {
},
$$slots: { default: true }
});

return {};
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export default function Hello_world($$anchor) {
var h1 = root();

$.append($$anchor, h1);
return {};
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ function Hmr($$anchor) {
var h1 = root();

$.append($$anchor, h1);
return {};
}

if (import.meta.hot) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default function State_proxy_literal($$anchor) {
$.bind_value(input, () => $.get(str), ($$value) => $.set(str, $$value));
$.bind_value(input_1, () => $.get(tpl), ($$value) => $.set(tpl, $$value));
$.append($$anchor, fragment);
return {};
}

$.delegate(["click"]);
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export default function Svelte_element($$anchor, $$props) {

$.element(node, tag, false);
$.append($$anchor, fragment);
return {};
}

0 comments on commit e42bb61

Please sign in to comment.