Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding to store through a component does an unnecessary set #10217

Closed
sickl8 opened this issue Jan 18, 2024 · 2 comments
Closed

Binding to store through a component does an unnecessary set #10217

sickl8 opened this issue Jan 18, 2024 · 2 comments

Comments

@sickl8
Copy link

sickl8 commented Jan 18, 2024

Describe the bug

Binding to a store through a component does an unnecessary set to the store with it's current value

Reproduction

<!-- Main.svelte -->

<script lang="ts">
	import { type Writable } from "svelte/store";
	import CheckboxComponent from "./CheckboxComponent.svelte";
	
	type MyWritable<T> = Writable<T> & {
		value: T;
		subs: Set<(newValue: T) => any>;
	};
	function log(...args: any[]) {
		console.log(new Error().stack?.replace(/.*Error\n/, ""))
		console.log(...args);
	}

	function createWritable<T>(initial: T): MyWritable<T> {
		let ret: MyWritable<T> = {
			value: initial,
			subs: new Set(),
			set(newV) {
				// compiler/compile/render_dom/invalidate.js:108						invalidate svelte variable ?
				// compiler/compile/render_dom/invalidate.js:125						invalidate svelte store ?
				// compiler/compile/render_dom/wrappers/InlineComponent/index.js:372	where invalidate for both is created ?
				log({ set: newV });
				ret.value = newV;
				ret.subs.forEach(subscriber => subscriber(ret.value));
			},
			update(callback) {
				let newV = callback(ret.value);
				log({ update: newV });
				ret.set(newV);
			},
			subscribe(subscriber) {
				subscriber(ret.value);
				log({ subscribe: subscriber });
				ret.subs.add(subscriber);
				return () => {
					log({ unsub: subscriber });
					ret.subs.delete(subscriber);
				};
			},
		};
		return ret;
	}
	const writable = createWritable(false);
</script>

<!-- binding to elements directly does not trigger a set on the store -->
<input type="checkbox" bind:checked={$writable} />
<CheckboxComponent bind:checked={$writable} />

<!-- CheckboxComponent.svelte -->

<script lang="ts">
	export let checked: boolean;
</script>

<input type="checkbox" bind:checked>
<!-- could also be just a <div>{checked}</div> and it would be the same result -->

Logs

at log (http://localhost:5173/src/pages/components/BindSet.svelte?t=1705537115510:131:14)
    at Object.subscribe (http://localhost:5173/src/pages/components/BindSet.svelte?t=1705537115510:151:4)
    at subscribe (http://localhost:5173/node_modules/.vite/deps/chunk-2KUOQYVC.js?v=90f11c1d:87:23)
    at component_subscribe (http://localhost:5173/node_modules/.vite/deps/chunk-2KUOQYVC.js?v=90f11c1d:96:32)
    at instance (http://localhost:5173/src/pages/components/BindSet.svelte?t=1705537115510:170:2)
    at init (http://localhost:5173/node_modules/.vite/deps/chunk-2KUOQYVC.js?v=90f11c1d:2166:23)
    at new BindSet (http://localhost:5173/src/pages/components/BindSet.svelte?t=1705537115510:201:3)
    at createProxiedComponent (http://localhost:5173/node_modules/svelte-hmr/runtime/svelte-hooks.js?v=90f11c1d:341:9)
    at new ProxyComponent (http://localhost:5173/node_modules/svelte-hmr/runtime/proxy.js?v=90f11c1d:242:7)
    at new Proxy<BindSet> (http://localhost:5173/node_modules/svelte-hmr/runtime/proxy.js?v=90f11c1d:349:11)
BindSet.svelte:12
 {subscribe: ƒ}
  > subscribe: value => $$invalidate(0, $writable = value)[[Prototype]]: Object
BindSet.svelte:11
     at log (http://localhost:5173/src/pages/components/BindSet.svelte?t=1705537115510:131:14)
    at Object.set (http://localhost:5173/src/pages/components/BindSet.svelte?t=1705537115510:140:4)
    at Array.checkboxcomponent_checked_binding (http://localhost:5173/src/pages/components/BindSet.svelte?t=1705537115510:184:12)
    at checkboxcomponent_checked_binding (http://localhost:5173/src/pages/components/BindSet.svelte?t=1705537115510:44:47)
    at bind (http://localhost:5173/node_modules/.vite/deps/chunk-2KUOQYVC.js?v=90f11c1d:2099:5)
    at http://localhost:5173/src/pages/components/BindSet.svelte?t=1705537115510:58:31
    at flush (http://localhost:5173/node_modules/.vite/deps/chunk-2KUOQYVC.js?v=90f11c1d:1304:30)
BindSet.svelte:12
 {set: false}
BindSet.svelte:11

System Info

System:
    OS: Linux 5.10 Ubuntu 20.04.6 LTS (Focal Fossa)
    CPU: (4) x64 Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
    Memory: 10.57 GB / 12.45 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 18.19.0 - ~/.nvm/versions/node/v18.19.0/bin/node
    npm: 10.2.3 - ~/.nvm/versions/node/v18.19.0/bin/npm
    pnpm: 7.24.3 - /usr/bin/pnpm
  npmPackages:
    svelte: ^4.2.1 => 4.2.1

Severity

annoyance

@Prinzhorn
Copy link
Contributor

#6298 and more generally #5689

@dummdidumm
Copy link
Member

Closing as a duplicate of those referenced issues

@dummdidumm dummdidumm closed this as not planned Won't fix, can't repro, duplicate, stale Jan 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants