tc39 / proposal-signals

A proposal to add signals to JavaScript.
MIT License
2.78k stars 52 forks source link

No effects outside of frameworks? #149

Open wimbarelds opened 4 weeks ago

wimbarelds commented 4 weeks ago

In the proposal's current form (and with the current philosophy); that is without an implementation of effects; it seems the Signals proposal would exclusively be of value to framework authors / framework users. Even in the very first example of using signals, a framework is imagined to provide the "effect" function, because without such an effect Signals lack dont really do anything.

In frameworks almost all interactions (DOM mutations/rerenders, etc) happen through effects.

Effects should be available outside of frameworks. Someone prototyping code in chrome devtools, codepen, or generally in VanillaJS, should be able to make full use of signals.

Frameworks may need more finegrained / low-level access to implement effects in a way that works with their render cycle/timings; but that should not preclude a basic implementation of effects from being available outside of frameworks.

sorvell commented 4 weeks ago

See https://github.com/proposal-signals/proposal-signals/issues/136#issuecomment-2041157595

wimbarelds commented 4 weeks ago

Not sure if I should continue discussion in that thread or here. If preferred in that thread I can move it there- though I think the ask/feedback is very slightly different.

My point isn't that an effect cannot be implemented, but that javascript outside of frameworks seems to not have been taken into consideration / doesn't have a good usage path. Even the example referenced there (which is described as "too basic to be useful, do not copy/paste") isn't easy to read or intuitive to come up with (being that it feels like it's "abusing" computed for something unrelated to actually creating a computed value).

NullVoxPopuli commented 4 weeks ago

an effect cannot be implemented,

The example in the README can be implemented in a super thin library, which can be exposed in signal-utils https://github.com/NullVoxPopuli/signal-utils/ -- but due to the concerns listed, I think we'd probably want it under an unsafe or subtle export (in the library -- because it would have a memory leak by default). I do agree with you that "just trying things out" in the browser outside of the framework is super useful -- but it's hard to make something work for everyone and be safe.

I'm going to try to add this type of effect (and anything else anyone comes up with to signal-utils, because I think it's valuable to have runnable examples folks can play with and import, evaluate, etc.

The main issue I've come across while evaluating effect implementations is that we have to, at some point, unwatch the computeds.

All of this is much easier if you have using / Symbol.Disposable, or some rendering layer to integrate with an owner/container to manage lifetimes for you

littledan commented 4 weeks ago

Would people be Ok with merging this thread into #136?

jonhartmann commented 2 weeks ago

I want to ➕ this topic - I think the idea that effect() isn't implementable within a standard application limits its utility. If I can't get rid of the framework, how does this help me? I can assume it has slightly better performance characteristics, but I get the same functionality out of tools like Recoil with React already. The real value is when this becomes Vanilla and we can ditch the libraries.

I get that its hard, but if the system did implement an effect and understand how to handle watchers, it would give the users a complete package.

JosXa commented 1 week ago

The main issue I've come across while evaluating effect implementations is that we have to, at some point, unwatch the computeds.

  • How do you do that without an owner? or container?

Isn't this as simple as calling the cleanup function returned by the effect? If I'm building a production-ready Node app without a framework using native signals, I can be expected to know that cleaning up effects is something I have to take care of. Or am I missing the point?