As the creator of SolidJS, I was very influenced by React when designing the library. Despite what people might believe by looking at it, it wasn't...
For further actions, you may consider blocking this person and/or reporting abuse
In many more situations than we might think, programmers have more information than a highly optimized compiler.
Wouldn't it be enough for a framework to open up the possibility of optimization by providing options for programmers to leverage this information when they need it?
For example, if a function is "pure", the result of the function could be cached, but the decision of whether to cache the result should be entirely up to the programmer.
Yeah. In essence though you could say that is what
React.memo
,useMemo
, anduseCallback
. The problem is it isn't really what people want to be thinking about. They ignore performance, then find out that some leaf component is inexplicably re-rendering 8 times on some small mutation. They have no idea how to trace it and they start slapping those on everywhere. Eventually they get it down to 2 and call it a day because they still are missing something. 6 months they come back and realize its running 4 times now because someone did something else in a parent component. And so on.Models that remove the idea of "optimization mode" and just are more optimal to begin with have some benefits. React started looking into compilers, but you get this with Signals too just by their design.
I do not like React's memo function.
Memo is a function that reduces the cost of V-DOM, but I think frameworks like Solid and Svelte have proven that V-DOM itself is just pure overhead.
The implementation using signals is to say that there will be no performance problems in most cases even without additional optimization for excessive calls in the Limits to Locality of Thinking section.
But when I read the article again, it seems that the original content of the article is the same claim.
I would like to understand how the signals work to update the dom. The jsx-runtime transforms everything into DOM elements and if one has a Signal the update of the element is registered during the jsx-runtime ? And how is it solved if you use signals for conditional renders?
In basic:
We transform everything to lazy evaluated expressions so we don't great the DOM elements up front. You can picture we wrap everything in functions.
I tried to explain this a couple years ago.. admin.indepth.dev/solidjs-reactivi...
I think this article isn't the clearest but I try to make it consumable.
I figure out reactivity with conditional renders only if are inside a node. I realized one thing that I don't get out of, and that is when there is reactivity mixed with static things. Example:
What would this JSX look like in HyperScript?
Something like this using
h(null)
?I implemented it in this way, however, creation works fine because I can use a
documentFragment
to append and return, however modification doesn't work well because the editing thedocumentFragment
doesn't update the real DOM... So I imagine that here is necessary to track theparentNode
(initialdiv
) and use it during the modification... Or how you solved this?Thanks a lot for your help @ryansolid
I finally resolved changing the hyperscript children to array, this way I can execute in order knowing the parent:
I have managed to implement a draft version to use jsx and signals in web-components. I am very grateful and the article you have passed me helped me to understand the basics of signals better. Thank you very much for the article.
for future readers that link is dead now, but the article is available here (with no attribution) angularindepth.com/posts/1289/soli...
or on archive.org here with no css web.archive.org/web/20221005075537...
Getters are an antipattern, things become impossible to track down, the language becomes less powerful (no ability to use destructuring, not in functions arguments and not in objects, etc), things become unpredictable (merged effects = values that come from props are re-evaluated).
The exact code that was causing me problems with the merged effects + props getters is:
I never expected that code to run more than once. I was shocked.
An
isSignal
on this context doesn't make sense, it has no value to know if something is a signal (for the value that being a signal provides), in any case you will unwrap the value, context github.com/solidjs/signals/issues/8About props, you can freeze them with
Object.freeze(props)
Anyway, I do love solid and the ideas you came with, signals, enchanted by dom-expressions output, just feeling pity it crossed the line with the props getter stuff, but that's just my preference. Thanks Ryan!, great source of inspiration
Yeah it definitely pushes against the language a bit, although using objects of functions for props is also awkward because shape changing... can't really spread test the existence of something in a reactive way. Ie.. track something that isn't there yet. Not having isSignal has been a blessing though so I doubt we'd ever expose that as an external API. Which is difficult because if we are building a core library that people might use directly hiding it might be challenging if it was included. So while there are a couple places I wouldn't mind internally leveraging the optimization it just can't exist out there so will have to see what can be done.
Thanks for the article, still trying to wrap my mind around how signals work..
How does a global state fit with locally of thinking? any disadvantage or using signals as a global state?
You are right in that is the 3rd boundary point into our component. I didn't talk about it much in the article. It is really a 3rd category as you have a bit of both qualities as it is a lot like props where you have data and explicit mutators coming in, but you don't get to define the interface(the global store does) similar to how it is when you consume child components.
If the interface is well defined then in a sense this is no different than any composition pattern in components you use. Like custom Hooks/Primitives. Whether you own the state or created doesn't impact the mechanics of the component.
However, since you do not know the side effects of your actions the recommendation for global state design it is generally encouraged to be as specific as possible with mutation API. For instance this is better:
In general Signals(or Solid's Stores which are nested Proxy Signals) are great for global state. Most global state management libraries are some sort of event emitters and this one plays first party with the framework. But given above I do recommend not just exposing the setters directly if possible, and design an explicit mutation API.
Thanks!! will try out solid, interested to see how it works
How is development on Solid 2.0 with global signals going? Looking forward to using signals, memos, & resources for global state management!
React has passed many values down over the years. Probably hundreds of trillions. And I hope we learn from all of them.
Btw, unidirectionality meant a lot more than just values being passed down. Flux was the unidirectional thing when they first described it, and React was described as a "declarative rendering framework." Declarative rendering with JSX is unidirectional, but it's kind of boring. What's interesting is the full cycle from event to DOM render. That's what MVC vs unidirectionality was about. Without something like Flux, React is an MVC framework. People forget the origins, because most apps require one data source and a few trivial state changes, so it doesn't matter. But React and Flux were designed in an environment that was much more complex than most applications: a chat app. The way most React apps are architected today is not much better than what came before React. It's event handlers controlling various states. JSX and components are the real improvement that stuck.
@ryansolid if you can watch my UtahJS talk and come away still not agreeing that React is an MVC framework, I'll give you the gift card they gave me for speaking. youtu.be/yCrrkBV4-K8?si=uxMbSQv-2q...