What Are Signals?
Recently, the JavaScript community has been buzzing about signals. Their rise in popularity can be traced back to Soli...
For further actions, you may consider blocking this person and/or reporting abuse
Q: "What are signals?"
A: A meaningful step forward for frameworks to get closer to catching up with what Vue was doing in 2017, though with manual effort instead of it being handled automatically. Also known as "a waste of your time doing something the framework should handle for you for free".
If we are going to play the When game, we will end up .. or start.. somewhere in the previous century. Semaphores...anyone?
And before Vue there was (S)[github.com/adamhaile/S] :-)
Are you saying Vue doesn't handle it automatically? You really can't get less automatic than what Vue does: ˋconst count = ref(0); ref.value = 1ˋ. How can you make it more automatic?
No, I am saying Vue has been handling reactivity for you since day one. Especially the features specific to Vue 2 (hence 2017 being mentioned). And I am referring to the declarative Options API. You are referencing the lower-level API that hooks into the reactivity engine (Composition API). That approach is useful when handling niche edge cases or building a library. However, the Options API is specifically designed to solve the common problems of writing applications.
JSFiddle of above
Notice how I don't need to do anything more than just put the code in the correct section and the framework handles everything. Reactive state is free. Until the browser mentions that value was changed, no reactive code is executed, it is the same from a memory or CPU stand point as if it were static. Derived state is also free, it only re-computes the computed data when something it is dependent on reactively changes, and then the output is cached, so it executes the least amount possible. Note that you never need to babysit any of this, or explicitly spell things out, like what is/isn't reactive, or what to watch, or when to re-render the DOM. The framework can handle all of this automatically, and it can do a better job than you can doing it by hand. This is why Vue apps are 2-6 times faster than React apps. They are not the same.
Notice how there are specific sections for your code. It is organized by default, and the features of the framework are built in to this organizational structure. I cannot overstate how important this is. Every frontend framework should be copying this approach. You can go to any component, in any codebase in the world and instantly know where everything is. There is no need to invent and document and train every new person on "how things are done" or "where things go" in your codebase. You can take your intern, point them at the official Vue docs, and say "do it that way". Then come back 20 minutes later and they are already doing a commit (true story).
You will inevitably need to create bespoke patterns for your projects that are unique to that specific project's purpose. So let the framework solve these common problems for you, so you can focus on the parts unique to the app you are trying to build. Vue gets out of your way and lets you make things quickly, and in a consistent, testable, scalable, modular, performant, and organized-by-default way. No other framework even comes close. And we didn't even talk about Pinia.... it's so good, I'm convinced it was sent back in time from the future.
Vue3 > Vue2. If you just follow conventions you also know exactly where code is going to be. And the structure of Vue2 is the exact reason why the Composition API was created, because that structure sucks.
There are no conventions. You must invent your own conventions and organizational structure. And no matter how organized you think you are, you aren't. And even if you are, the second you leave the project no one will be there to enforce your conventions. The framework comes with a built in organizational pattern that rewards you for using it.
What about the Options API's approach "sucks"? The only valid critique is Mixins, and they're not even that bad unless you're doing nested mixins, but even then an editor-level solution would solve that. But until there is one, Mixins being pointed to is valid. But that's a pretty minor downside compared to the massive downsides of Composition API. It's just another way of making spaghetti.
It's not hard to come up with a logical convention. It's just common sense where you put things. For example, you could follow the Options API convention.
The Composition API is structured in a functional, non-spaghetti way. I don't know how to explain this, even if it seems logical in my head, but everything is completely separate, unless you make it be. You can only access the variables you can actually see, you can't mess with other things. There are no accidental side effects, it's all pure. It just works like normal JS and easy to type with TS. With the Options API it feels all jumbled up like spaghetti and all proprietary and connected to Vue. You can't just something how you want to. For example, composables aren't something Vue invented, they're a pattern you can use. You can do things how you want and it's super customisable.
Hopefully I explained it well, but I probably didn't. If you want to know what I mean, extract all the logic for a to-do app into a different file, but still so that you can do things in the file with the template. With Composition API, you can make a composable that holds the state and returns all the state and functions to interact with the state. That just doesn't work with Options API.
What precisely distinguisches "States" from "Signals"? Sounds as if they are more or less the same - despite the different name.
Reflecting state changes in the DOM is handy, but what, if your logical context needs a more complex interaction than just updating a dom element? Assume you need to fetch a value from a database, if a "signal" changes it's value?
And how do you avoid update loops? A triggers B, B trigger A and so on... A Dom element might have an .onChange-event, that cahanges a signal...
Signals are states with a joined effect, or function that runs when it changes. This effect that runs doesn't just have to update the DOM. Frameworks like Solid will detect where the signal is being used within the JSX and create the necessary DOM update code.
The current design doesn't take into account if you trigger A from B, and B from A. You'll need to introduce either a limit to track the number of subscriber calls and stop at a certain number, or you could set up a lock so when one subscription is running, other ones won't be called. In most cases, major refactoring will be needed.
But Isn´t this what all states do? See Van States or React State:
Most modern programming languages know getters and setters for at least 30 years see Mutuator method, so it is not a new concept. But instead invoking a function when a state has changed, a setter function is invoked before a state has changed. This gives you more control over the process (e.g. limiting the value range of a variable change) and makes it unnecessary to store the value of the state object before it was changed (which some state libraries provide).
A react state is different than just a plain state. A state on it's own is just data at a certain point in time. React has type of state is is bound to an effect for re-renders. I don't know about Van states to give any input there.
I could be wrong but I welcome any correction.
Van states are more or less variables that can be bound to any DOM property. So, a "plain state" ist more or less a variable in that context. An "immutable state" would just be a constant. see Immutable Object
As far as I see, the concept of "immutable state" makes only sense in platforms like React, where you need to ensure, that a state does not change during a page rendering.
So, it´s interesting to see, how much effort it takes to implement signals in the context of React, which otherwise would be a very simple interaction...
You know you are old when you read about the latest trend and say to yourself: "Isn't this exactly the same as [NSERT TECH] that I was doing 15 years ago?"
In this particular case it was RETE algorithm, there are several implementations for different programming languages. Invented in 1979 apparently.
Anyway, you define rules that trigger on certain states. When you modify the state the rules trigger in cascade. It's pretty neat and very useful in solving business rules.
[INSERT TECH] = Knockout.js
Amazing read! Thanks for posting.
Thanks for the article! Somehow it reminds me of rxjs Subject :)
good article
cool rundown, thank you
docs.djangoproject.com/en/4.2/topi...
What's different between signals and a regular old pub-sub pattern?
I am curious about what React 19 will look like.
In various meanings.
Thanks for the article.