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

Notifying signal update with reference types #235

Open
tzakharko opened this issue Oct 9, 2022 · 4 comments
Open

Notifying signal update with reference types #235

tzakharko opened this issue Oct 9, 2022 · 4 comments

Comments

@tzakharko
Copy link

A signal will only fire if a "new" value is assigned. So if I use a signal with a reference type, e.g. an array, updating the value will not actually fire the signal. Cloning works but sounds wasteful. It would help if there were a way to fire a signal manually after update in this case.

@KnisterPeter
Copy link

If you want to handle references, I think it's best to use immutable data structures.
That does not involve full cloning but only 'recreate' the required parts of your data structure.

@tzakharko
Copy link
Author

@KnisterPeter this still means making shallow clones for dictionaries. Unfortunately, JavaScript is not very good at immutability. I mean, it's not a big deal and a clone on user interaction won't even be measurable, but it does make the code more awkward.

@eddyw
Copy link
Contributor

eddyw commented Oct 14, 2022

Signals use versioning internally, each update increases a version number, so the value isn't really used to know if a computed or effect should update.

With that in mind, you can create your own abstractions using the exact same idea:

function refSignal<T>(value: T) {
	const version = signal(0);
	const notify = () => version.value++;

	return {
		notify,
		get value() {
			version.value; // Subscribe
			return value;
		},
	};
}

We create a signal version for the sole purpose of allowing other computed or effect to subscribe to it. It's value can be anything but a number is pretty cheap so that'd work just fine:

const s = refSignal(["hello"]);

effect(() => {
	console.log("Current value:", s.value);
});

s.value.push("World!");
s.value.push("!!!");
s.notify();

// Effect logs:
// Current value: [ 'hello' ]
// Current value: [ 'hello', 'World!', '!!!' ]

@tzakharko
Copy link
Author

@eddyw thanks for the suggestion, that’s very similar to the interim solution I am currently using, only I use a Boolean and invert it every time to avoid dealing with overflows (probably will never happen in practice but better safe than sorry)

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