DEV Community

Cover image for Implementing Signals from Scratch

Implementing Signals from Scratch

RATIU5 on September 28, 2023

What Are Signals? Recently, the JavaScript community has been buzzing about signals. Their rise in popularity can be traced back to Soli...
Collapse
 
thejaredwilcurt profile image
The Jared Wilcurt

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".

Collapse
 
dannyengelman profile image
Danny Engelman • Edited

If we are going to play the When game, we will end up .. or start.. somewhere in the previous century. Semaphores...anyone?

Collapse
 
artydev profile image
artydev

And before Vue there was (S)[github.com/adamhaile/S] :-)

Collapse
 
coolcucumbercat profile image
coolCucumber-cat

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?

Collapse
 
thejaredwilcurt profile image
The Jared Wilcurt

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.

<template>
  Display reactive values: {{ count }} {{ doubledCount }}
  <button @click="count++">Modify reactive value from template</button>
  <button @click="increment">Modify reactive value in methods section</button>
</template>
<script>
export default {
  data: function () {
    return {
      count: 0
    };
  },
  methods: {
    increment: function () {
      this.count++;
    }
  },
  computed: {
    doubledCount: function () {
      return this.count * 2;
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

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.

Thread Thread
 
coolcucumbercat profile image
coolCucumber-cat

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.

Collapse
 
efpage profile image
Eckehard

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...

Collapse
 
ratiu5 profile image
RATIU5

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.

Collapse
 
efpage profile image
Eckehard • Edited

But Isn´t this what all states do? See Van States or React State:

React components has a built-in state object.
The state object is where you store property values that belong to the component.
When the state object changes, the component re-renders.

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).

Thread Thread
 
ratiu5 profile image
RATIU5

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.

Thread Thread
 
efpage profile image
Eckehard • Edited

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...

Collapse
 
qwertme profile image
Eric di Domenico • Edited

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.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

[INSERT TECH] = Knockout.js

Collapse
 
tailcall profile image
Maria Zaitseva

Amazing read! Thanks for posting.

Collapse
 
bwca profile image
Volodymyr Yepishev

Thanks for the article! Somehow it reminds me of rxjs Subject :)

Collapse
 
hasanelsherbiny profile image
Hasan Elsherbiny

good article

Collapse
 
artxe2 profile image
Yeom suyun

I am curious about what React 19 will look like.
In various meanings.

Collapse
 
samuelthng profile image
Sam

What's different between signals and a regular old pub-sub pattern?

Collapse
 
sabbir2609 profile image
sabbir2609
Collapse
 
oli8 profile image
Olivier

cool rundown, thank you

Collapse
 
themaker profile image
mich_thedev

Thanks for the article.