It's a collaboration between multiple library maintainers, attempting to standardize and unify their shared change-tracking approach.
I wonder some years down the future, if there will be no need for JS frameworks since a lot of what they offer will be integrated into JS itself.
In the time that I’ve been using ClojureScript, the whole react community has switched to hooks. I find it so baffling - requiring your entire data structure to be contained within your component lifecycle? The thousands of calls to individual “useState” to track the same number of state items? The fact that every function is closing over historical state unless you manually tell it to change every time the variable does — and then this last bit in combination with non-linear deep equality comparisons?
I recently have been in the process of switching phrasing.app from reagent atoms to preact/signals for performance reasons (and as part of a longer horizon move from react to preact) and I have to say it’s been fantastic. Maybe 50 lines of code to replicate reagent atoms with preact/signals, all the benefits, and much much faster.
Very happy that there is react-like library so devoted to first class support of signals.
Oh boy. The youth of the author is really visible.
I'm sure some 80 year olds before us thought the same of us using that term.
"Traditional" hooks are 6 years old. I think it's to early to call it traditional. Given that literally everyone else looked at this "tradition" and chose differently. Namely, signals.
Signals were popularized by SolidJS, but SolidJS's Ryan Carniato will keep telling you that what everyone calls signals now has its roots in libs like KnockoutJS from 2010. And everyone has been busy using signals for the past three years.
Given the amount of frameworks that implement signals today (including monsters like Angular), it's React who's not following tradition.
Traditional? I remember when React was the new kid on the block. I am getting old! :-D
By default, usestate causes unnecessary rerenders which signals avoid (all automatically).
<div id="myoutput">Enter a name</div>
<input type="text" onchange="document.getElementById('myoutput').innerText = `Hello {name}!`" />
One upside of this approach is that the only subtree that needs to be re-rendered is the specific element whose state got mutated.
Another upside of this approach is that the code doing the mutation is very close to the actual UI element that triggered it. Of course, this rapidly turns into a downside as the size of the codebase grows...
When you ignore the performance aspect, React has the objectively least amount of boilerplate for reactivity.
The question, that I genuinely don't know the answer to, is a) whether the performance improvement is worth it, and b) whether that's still the case after the compiler.
It isn't, given that React requires you to provide an array of dependencies when using useMemo and useEffect. The point of React is to automatically update the DOM when a virtual DOM tree gets modified.
Also, it seems that with signals you must use immutable values only. Imagine if you have, let's say, a text document model, and you need to create a new copy every time the user types a letter. That's not going to work fast. And there will be no granular updates, because the signal only tracks the value (whole document), not its components (a single paragraph).
Also the article mentions rarely used preact and doesn't mention Vue. Vue can track mutable object graphs (for example, text document model). But Vue uses JS proxies that have lot of own issues (cannot access private fields, having to deal with mixing proxies and real values when adding them to a set, browser APIs break when a proxy is passed).
Also I don't like that React requires installing Node and compilation tools, this is a waste of time when making a quick prototype. Vue can be used without Node.
Also, for nested data structures you need to either do path copying, or use "modification boxes" [1].
[1] https://en.wikipedia.org/wiki/Persistent_data_structure#Tech...
> Also I don't like that React requires installing Node and compilation tools, this is a waste of time when making a quick prototype. Vue can be used without Node.
React can be used without Node too, and this has always been the case to the best of my knowledge. You can check out this gist which is linked from the official docs[1]: https://gist.githubusercontent.com/gaearon/0275b1e1518599bbe... Vue can be used without Node.
You lose a lot though! You don't get minification and tree shaking, single file components, or hot module reloading. In practice, HMR outweighs the cost of setting up a Node/Deno/Bun environment.Too small. Imagine if you have a 2GB mutable file. Each keystroke in the middle of the file has to move the whole 2nd gigabyte backward.
Funnily enough, back when storage was slow enough that saving a text document involved a progress bar, one of the big advantages Word had over competitors was lightning fast saves, which they accomplished by switching to an immutable data structure. That is, while others would update and save the data, Word would leave it untouched and just append a patch, skipping lots of time spent rewriting things that an in-place edit would shift.
The “copy everything” mental model of immutable programming is really about as wrong as a “rewrite everything” mental model of mutable programming. If it happens it’s bad code or a degenerate case, not the way it’s supposed to happen or usually happens. Correctly anticipating performance requires getting into a lot more detail.
event.listenTo(render);
event.emit();
And that we should do this instead: property.listenTo(render);
property.set([property.get()[0]]);e.g:
function MyComponent({ disabled }: { disabled: Signal<boolean> }) {
// ...
} function MySubComponent({ disabled }: { disabled: Signal<boolean> }) {
// ...
}
function MyComponent({ disabled }: { disabled: Signal<boolean> }) {
return <MySubComponent disabled={disabled} />
}
passing the value on and on as you go down a component chain. Context lets you avoid all that.Where signals offer an important benefit is in localizing re-rendering. If you use context with regular, non-signal values the entire VDOM tree has to be re-rendered when the context value changes (because there's no way to know what code depends on its value). With signals you can change the value of a signal in the context without changing the context itself, meaning that the only part of the VDOM tree that gets re-rendered is the one using the signal.
With performance considerations out of the way context becomes a really interesting way to provide component composition without having to specify the same props over and over as you make your way down a chain.
That consideration is orthogonal to what the useful data is. It could be a signal, or not. In other words, signals are not an alternative to context.
Like, I understand why people aren't going full 3d game simulation style for applications. But I don't understand why things are as divergent as they are?
Is this just my off perspective?
I have similar questions on asset management. But I think that one makes a bit more sense, though? Game studios often have people that are explicitly owners of some of the media. And that media is not, necessarily, directly annotated by the developer. Instead, the media will be consumed as part of the build step with an edit cycle that is removed from the developer's workflow.
I feel like at some point we are gonna complete the cycle and have MVVM/MVC binding engines in frontend dev.
There is barely any difference left between createContext+useSignal vs. C# DataContext+ObservableProperty.
One way I frame such issues in my mind is that it's about who has control (and how much) over what is rendered and when on the screen I carry in my pocket. To some extent it is now Signal when I use the app. One day it might be my State instead.
Compare: "import a specific lightweight library and wire together as needed" vs "write the whole app in terms of a bloated framework".
I've been out of the frontend game for a while, but what does react give you that knockout and maybe some url management logic do not?
I guess components are supposed to standardize modularity, so you can easily import some random widget?
- auto rerender by comparing trees?
- track all changes by signals?