7 ms·
Am I the only one that thinks the vanilla js example is actually easier to read and work with? - "The setup is noise and boilerplate heavy." Actually the signa
by itsjustme2 2y ago
Am I the only one that thinks the vanilla js example is actually easier to read and work with?
- "The setup is noise and boilerplate heavy." Actually the signals example looks just as noisy and boilerplate heavy to me. And it introduces new boilerplate concepts which are hard for beginners to understand.
- "If the counter changes but parity does not (e.g. counter goes from 2 to 4), then we do unnecessary computation of the parity and unnecessary rendering." - Sounds like they want premature memoization.
- "What if another part of our UI just wants to render when the counter updates?" Then I agree the strawman example is probably not what you want. At that point you might want to handle the state using signals, event handling, central state store (e.g. redux-like tools), or some other method. I think this is also what they meant by "The counter state is tightly coupled to the rendering system."? Some of this document feels a little repetitive.
- "What if another part of our UI is dependent on isEven or parity alone?" Sure, you could change your entire approach because of this if that's a really central part of your app, but most often it's not. And "The render function, which is only dependent on parity must instead "know" that it actually needs to subscribe to counter." is often not an unreasonable obligation. I mean, that's one of the nice things about pure computed functions- it's easy to spot their inputs.
- duxup 2y agoI agree the initial example is easier to read, but it has problems as stated.
- leononame 2y agoWhy do you think this is premature memoization? This is an example, boiled down to a simple function. Do you think people just came up with the use case for this without ever having needed it? I think an effort in standardizing signals, a concept that is increasingly used in UI development is a laudable effort. I don't want to get into the nitty gritty about what is too much boilerplate and whether you should build an event system or not, but since signals are something that is used in a variety of frameworks, there might be a good reason to it? And why not make an effort and standardize them over time?
- 38 2y ago> I don't want to get into the nitty gritty about what is too much boilerplate and whether you should build an event system or not You're basically saying you want this thing, but you don't want to have to justify it
- shermantanktop 2y agoThe rationale for it is the fact that multiple frameworks provide their own versions of this mechanism. The proposal is to relocate extremely popular and common functionality from framework space to the language/runtime space. The popularity of React is itself the rationale for the utility of this idea, and any terse version of the rationale is for show. Is that a good enough rationale? Maybe, maybe not, but you are shooting the messenger.
- refulgentis 2y agoMost importantly: OP is right re: vanilla example is most legible. Reading the proposal, I have no idea what this "Signal" word adds other than complexity. Less important: I really, really, really, really, am reluctant to consider that is something that needs standardizing. Disclaimer: I don't have 100% context if this concept is _really_ the same across all these frameworks. But frankly, I doubt it, if it was that similar, why are there at least a dozen frameworks with their own version?* Also, I've lived through React, Redux, effects, and so on becoming Fundamentally Necessary, until they're not. Usually when it actually is fundamental you can smell it outside of JS as well. (ex. promises <=> futures). I've seen 1000 Rx frameworks come into style and go out of style, from JS to Objective-C to Kotlin to Dart. Let them live vibrant lives, don't tie them to the browser. * I know that's begging the question, put more complex: if they are that similar and that set in stone that its at a good point to codify, why are there enough differences between them to enable a dozen different frameworks that are actively used?
- catlifeonmars 2y ago> But frankly, I doubt it, if it was that similar, why are there at least a dozen frameworks with their own version?* Welcome to the fashion cycle that is JavaScript. Given a few years, every old concept gets reinvented and then you have half a dozen frameworks that are basically the same but sufficiently different so that you have to relearn the APIs. This is what I think standardization helps circumvent A good standard library prevents fragmentation on ideas that are good enough to keep getting reinvented
- briantakita 2y agoSince reactivity is not baked into Javascript. Adding reactivity is going to add abstraction overhead. It's meant to be used if it's needed. Not necessarily a default way to work with state. In my experience, the big benefit is the ability to make reactive state modular. In an imperative style, additional state is needed to track changes. Modularity is achieved using abstraction. Only use when needed. > Sounds like they want premature memoization It's a balance to present a simple example that is applicable. Cases where reactivity have a clear benefit tend to be more complex examples. Which is more difficult to demonstrate than a simple, less applicable example.
- LittleDan 2y agoI think there is room for improvement in how we explain this. The problems aren’t really visible in this small sample and comes up more for bigger things. PRs welcome.
- briantakita 2y agoPerhaps mentioning the tradeoffs between a simple easy to explain example vs a more obvious comprehensive example. With links to more complex code bases? With a before & after?
- troupo 2y agoI wouldn't be surprised if Ryan Carniato already has a perfect explanation somewhere :)
- ksherlock 2y agoI agree. But look at Preact's signal documentation - https://preactjs.com/guide/v10/signals https://preactjs.com/guide/v10/signals "In Preact, when a signal is passed down through a tree as props or context, we're only passing around references to the signal. The signal can be updated without re-rendering any components, since components see the signal and not its value. This lets us skip all of the expensive rendering work and jump immediately to any components in the tree that actually access the signal's .value property." "Signals have a second important characteristic, which is that they track when their value is accessed and when it is updated. In Preact, accessing a signal's .value property from within a component automatically re-renders the component when that signal's value changes." I think it makes a lot more sense in a context like that.
- andrewstuart 2y ago>> In Preact, when a signal is passed down through a tree as props or context, I have found that passing props makes React-like applications very complex and messy and props are to be avoided as must as practical. The mechanism for avoiding props is Custom events. It concerns me to see the concept of signals being passed as props when surely signals/events should be removing the need for props?
- Pufferbo 2y agoYou don’t need to pass a Preact signal as a prop to get reactivity. If you’re using Preact, signal references will make your component reactive by default, and if you’re using React you can introduce reactivity by way of the useSignals hook or a Babel plugin. (1) React signals have become my go to state management tool. So easy to use and very flexible. 1: https://www.npmjs.com/package/@preact/signals-react https://www.npmjs.com/package/@preact/signals-react
- andrewstuart 2y ago>> React signals have become my go to state management tool. I've ditched almost all state in my React apps except state local to the component. Custom events do all the work for passing information around the application and directing activity. What do signals give me that events do not?
- catlifeonmars 2y agoI think it’s worth avoiding a change in design when you pass some threshold of complexity. The vanilla JS approach has some scaling limitation in term of state graph complexity, and the problem isn’t the ergonomics above and below the threshold, but discontinuous change in ergonomics when you cross that threshold
- tipiirai 2y agoDefinitely not. I prefer the vanilla version as well.
- deleted 2y ago[deleted]
- vundercind 2y agoI dislike both examples but find the Signals one far worse, no question. You can do it that way, but… why? When you could just not?
- flohofwoe 2y agoI was wondering about this awkward code: counter.set(counter.get() + 1) One would think that proper integration into the language also means getting rid of those "noisy" setter/getter calls.
- Offler 2y agoI much prefer the explicit get/set methods. MobX I think used the magic approach as did svelte and I believe svelte have realized it's a mistake. It makes it harder to reason about the code, better to be explicit.
- naasking 2y ago> Am I the only one that thinks the vanilla js example is actually easier to read and work with? Even if that were true for this example, the signal-based model grows linearly in complexity and overhead with the number of derived nodes. The callback-based version is super linear in complexity because you have an undefined/ unpredictable evaluation order for callbacks producing a combinatorial explosion of possible side effect traces. It also scales less efficiently because you could potentially run side effects and updates multiple times, where the signal version makes additional guarantees that can prevent this.