4 ms·
> Is the main draw of this performance? I guess performance in some cases, but mainly better developer experience. > I actually like how useEffect has an expl
by fabiospampinato 4y ago
> Is the main draw of this performance?
I guess performance in some cases, but mainly better developer experience.
> I actually like how useEffect has an explicit dependency array because you know when it will be triggered. Signal effects are implicit, and if you don't want it to trigger you have to use .peek(). I think I prefer React's explicit accessing of previous state to peeking when needed.
Fair, but in real code, or at least in the code that I write, peeking/untracking is not nearly as common as just reading a signal, on average this should be cleaner.
Also with this execution model you can support conditional dependencies, with the dependencies array model the array of dependencies is fixed, so your effect potentially will re-execute even for things that you don't really even read at some point.
> What is the purpose of batching other than performance?
There's no purpose to batching other than performance.
> Are there any possible negative effects of making multiple signal updates without batching?
A signal can cause other effects/memos to execute, and they can do arbitrary computations, so the cost of over-executing can be arbitrarily high.
- ZephyrBlu 4y ago> on average this should be cleaner I care more about explicitness than cleanliness though, especially if my effect touches 3+ state variables in a relatively large function. I can definitely believe that the average case is better with signals, but is the average case even important? I don't really care about the average case with something like state management because all the libraries are pretty good for that. It's the edge cases and complex state logic I care more about. Yeah useState, setState, prevState blah blah blah is a lot of overhead for the average case but I really like the explicitness it provides me in the not-so-average cases. What do you mean by conditional dependencies?
- fabiospampinato 4y agoEach case and each person is different, maybe dependencies arrays just work better for you. Potentially huge effects that read a couple of signals shouldn't exist, because you can always read the signal at the top and pass their values to an external function containing this huge amount of code. > What do you mean by conditional dependencies? Random example: useEffect ( () => { if ( !supportsThemes () ) return; if ( darkMode () ) { doSomething ( darkTheme () ); } else { doSomething ( lightTheme () ); } } In a reactive system this is all you have to write, if the first check never passes you only read "supportsThemes" so you will only be listening to that. If that passes in the future then maybe you'll start listening to "supportsThemes", "darkMode" and "darkTheme", but not "lightTheme". If "supportsThemes" becomes false again you'll automatically stop listening for "darkMode" and "darkTheme". In React this works differently, all those signals now become dependencies in the dependency array, the entire array will be diffed each time, whenever any of them change your effect will be re-executed, even if something you don't care about in that moment changed. Basically the same problem exists for hooks too, all hooks must be called all the time, which also as a side effect implies that some hooks calls need to become non-sensical, like if I don't have an onChange function what do I need to call useDebounce for it for? Should the hook support receiving a non-sensical null argument? Should I call it with a pointless noop function? This problem doesn't exist either in a reactive system, fundamentally because dependencies are dynamic, if you don't want to call a hook you can just not call it. If you want to nest effects you can do that.
- ZephyrBlu 4y ago> you can always read the signal at the top and pass their values to an external function Which is basically re-inventing a dependency array... except it's not explicit and now I have to look at another function as well. I don't understand how you are supposed to reason about complex effects with the signals model. > Random example Why would I want to complicate things with conditional effects though? It makes it so much harder to debug and reason about. > the entire array will be diffed each time, whenever any of them change your effect will be re-executed, even if something you don't care about in that moment changed An array diff on the order of ~10 elements isn't an expensive operation and I can implement conditional logic in React just like you've demonstrated here. What is different about signals in regards to conditional flows? > if you don't want to call a hook you can just not call it. If you want to nest effects you can do that I'm not convinced this is desirable. Complex implicit reactive effects seem fragile and difficult to debug and reason about. This is somewhat mitigated with React because of the Rules of Hooks, which gives you expectations about how your code/system should behave but even then people have complained about them being difficult to understand. This feels like a step backwards in terms of complexity. Without better tooling/observability (E.g. easily trackable effect history, value history, etc that is integrated into the dev env) implicit reactive dataflow based systems feel like they will be way harder to manage.
- dreamlifelike 4y agoYou’ve basically presupposed your conclusions re: the reactive approach, so yeah, if I were you I wouldn’t bother. Incidentally the “rules of hooks” are frustrating precisely because the expectations they impose around hook use are confusing and unintuitive.
- ZephyrBlu 4y agoI think dataflow mechanisms are really interesting, but I don't see them as being something easy to build a complex system on. I stated this very clearly, saying "complex implicit reactive effects seem fragile and difficult to debug and reason about". If you're building something that is heavily focused on computing values rather than more event driven effects I could see a reactive system being more useful and appropriate though. I'd love to hear from developers/teams who have built complex systems with a reactive framework (Solid, Signals, etc) to hear about the upsides and downsides of doing so.
- mmis1000 4y ago> but is the average case even important? I believe it does. Or there won't be a huge discrimination between theoretical react performance and real world web sites. React developer expect user to do all required optimization themselves. But web developer don't even care. (as long as they can ship it without serious complain) Developers always tend to do it the easy way instead of the proper way. If the easiest way is messed up. Then it is.
- localvoid 4y ago> I guess performance in some cases, but mainly better developer experience. It has better developer experience when you apply it to optimize performance. It is impossible to beat from-scratch recomputation in terms of DX.
- fabiospampinato 4y agoIt's a matter of opinion at best, for example I hate dependency arrays, and rules of hooks I find very weird, I understand why they are there, but to my brain they just fundamentally feel like workarounds for the lack of signals.
- localvoid 4y ago> for example I hate dependency arrays It is also an optimization and I agree that it is worse in terms of DX than autotracking dependencies.
- addicted 4y ago> Also with this execution model you can support conditional dependencies This is an anti-feature. To elaborate, a “conditional dependency” is still a dependency as much as any regular dependency would be. The only difference is that the conditional check is now taken outside the dependent code, (where the condition is both explicit and colocated with the dependent code) and put somewhere else, becoming less explicit and harder to find.
- fabiospampinato 4y agoThe conditional check in the example code I provided is pretty much just the if/else that one writes, that's as closely located as you can possibly write it I guess. Like if some signals are read under a branch that's never taken they are just never read, that's it. Also maybe there are good reasons for disliking it, but this seems harder to mess up, by default all dependencies are accounted for, automatically, that's not the case with dependencies arrays.