6 ms·
"Lots of people are still using it, but nobody can quite remember why." I can remember why. This, and every other article I've ever read arguing to replace Rea
by menssen 3y ago
"Lots of people are still using it, but nobody can quite remember why."
I can remember why. This, and every other article I've ever read arguing to replace React with Web Components, completely misunderstands the point of React. It isn't about JSX. It isn't about encapsulation. It isn't about reusability.
It is about enabling a design pattern where *the user interface is a pure functional transformation of the application state.*
I kind of feel like people get tripped up by the fact that "virtual DOM" and "shadow DOM" sort of sound similar. They have literally nothing to do with each other. The React "virtual DOM" allows you to *completely re-output the entire user interface* on every state change, which is not possible with any other design pattern, and is not possible without a framework, because actually re-rendering the entire tree on every state change isn't performative (or usable).
Anybody who is advocating an alternative to React needs to do one of two things:
(A) Make a convincing argument that a different design pattern is better. Some things we've tried, which most people think are worse:
1. Using the DOM as your data model (jQuery)
2. Manually writing virtual representations of every view (Backbone)
3. Auto-magically two-way binding some data structure with the DOM (Angular 1)
4. Observables (Ember, maybe Angular 2+?)
(B) Advocate a framework other than React that uses the same pattern as React, but improves the usability. I think the two places there is the most room for improvements are:
1. Animations
2. useEffect() in general
I have not seen anybody successfully do either A or B.
Recommended reading: https://acko.net/blog/get-in-zoomer-we-re-saving-react/ https://acko.net/blog/get-in-zoomer-we-re-saving-react/
- breadwinner 3y ago> It is about enabling a design pattern where the user interface is a pure functional transformation of the application state. This is only true for read-only components. There is no "pure functional" when you introduce state and interactivity. See here: https://mckoder.medium.com/why-react-is-not-functional-b1ed12a41323 https://mckoder.medium.com/why-react-is-not-functional-b1ed1...
- menssen 3y agoIt is possible with React to write an application where components have no internal state, every component is "read only," and all UI changes are state transitions in (something like) a redux store. This is rarely done, because there are pragmatic reasons (e.g., animations) not to, but it is possible. The other mistake alternatives make is to try to make components having internal state "easier." It should not be easier! Every single useX() is a statement that "I am violating the proper design pattern of this application," and it's a feature not a bug of React that you have to be obvious and intentional about it.
- dexwiz 3y agoIf one of the most popular APIs is a violation, then maybe the pattern is broken.
- DougBTX 3y agoIt’s a misremembering of history. The point of all the “pure functional” discussion was that rendering the UI now shouldn’t depend on how the UI was rendered earlier. The idea was to move away from the “create then update” paradigm to just “render”. React would be responsible for which elements need to be created and which can be updated in place. To achieve that, it doesn’t matter whether the state is local to a component or global across the application.
- breadwinner 3y ago> React would be responsible for which elements need to be created and which can be updated in place. That works for simple, read-only components. The moment the component starts managing its own interactivity you end up needing state, and at that point things break down. If you need to change props, you have to essentially recreate the component by changing key [1], and at that point, what is the benefit of React? [1] https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key https://legacy.reactjs.org/blog/2018/06/07/you-probably-dont...
- gherkinnn 3y agoI agree. useEffect should have been named useDangerousSideEffectAndThisIsNotALifecycleHook and the js influencers should have never compared useEffect to component lifecycles and the React team should have updated their docs and not wait 4.5 years to do so and the dependency array should absolutely not be optional.
- marcosdumay 3y agoThe idea of a reactive framework is that every interface component is either an event creator with no representation and that can update your application state, or an state viewer that has no inputs but can represent your state. It's decoupling those two that brings all the power. But the idea doesn't represent at all the web. So react is a mess of complex code trying to make the things you can create on the web behave like stateless pure components. Yet, it mostly works, and the react does indeed implement the idea that the interface is a pure functional transformation of the application state. (But I do disagree on claiming this the "entire idea", it's half of it at most.)
- tyingq 3y agoFair, though you can find plenty of stuff on the internet using React, but where the app/page itself performs abysmally. Meaning maybe there is some merit in approaches that are easier for lesser skilled teams to deliver in.
- menssen 3y agoThere is always space for options for "fast and easy" vs "robust and maintainable." Nothing will ever beat the following as tech demo for how easy it is to make interactive UIs, but anybody who ever tried to reason through a large Angular 1 application would seriously hesitate to want to use it for something much more complicated. <script src="angular.js" /> <input ng-model="inputValue"> <div>{{ inputValue }}</div>
- breadwinner 3y ago> Make a convincing argument that a different design pattern is better. Simple Model-View-Controller pattern works well for JavaScript, just as it does for ASP.NET Core, JSP and JSF, Ruby on Rails, Django and so on. Want proof? Browse this code: https://github.com/wisercoder/eureka/tree/master/webapp/ClientApp https://github.com/wisercoder/eureka/tree/master/webapp/Clie... This is the application: https://github.com/wisercoder/eureka https://github.com/wisercoder/eureka
- jitl 3y agoThe server side style of MVC you describe is a far stretch from how MVC is practiced in retained-mode UI frameworks like UIKit, Cocoa, or Backbone. It’s possible to make this style work fine with careful design and planning; Apple built web versions of Pages and Keynote using SproutCore (which evolved into Ember?) in 2013-era. In fact back then, everyone’s big app was MVC - usually Backbone. I worked on Airbnb’s host-side web app called “Manage Listing”, it had probably 30+ models, 150+ views, 100+ controllers in Backbone. There were many bugs in this scale of app around making sure the DOM reflected the latest change to some model. the engineering team regarded the more complicated screens as a nightmare to maintain in our fast paced environment with many teams touching the code. Engineers at Airbnb started to adopt React as a solution to the problems we all experienced with MVC - not because it was a “hot new thing”. When React came out, it was widely regarded as weird - it was more like “eww, this smells of PHP and needs a weird compiler, but pure function of state is a lot better than fiddling DOM manually…”. Eventually we replaced Manage Listing backbone views with React components one by one until there was no backbone left. React is still kinda weird but it does solve this problem the best out of the modern frameworks. It’s happy to over-render by default and prefers a correct DOM-for-state over everything else. It’s clear thought that the mental models popularized by React are worth it - now Apple and Google are switching to the React model in their own frameworks.
- breadwinner 3y agoMVC is a proven and popular technology. It works very well, otherwise it wouldn't be so popular. I notice you allude to "problems we all experienced with MVC" without mentioning any. Surely if there are so many problems, you would be able to mention one?
- MrPatan 3y agoPreach. Angular 2+, btw, can (and should) be used the same way. V=f(S) is the only sane way to live. Just don't change application state from a component lifecycle function and you're golden.
- tshaddox 3y agoI too remember building interactive web sites with jQuery. It was never fun creating, for instance, an interactive list view where each item can be modified in client state and new items can be added. This was the problem for which React provided a major "Aha!" moment.
- QuadmasterXLII 3y agoWith modern browsers, "completely re-output the entire user interface on every state change" is kinda viable. I recently wrote a trebuchet simulator app (hastingsgreer.github.io/jstreb) without a framework. instead I wrote a "rebuild UI" function that I call on every new state, and the user experience is super snappy
- stickfigure 3y agoIt doesn't seem to work at all in Chrome, so maybe not the best example.
- QuadmasterXLII 3y agoAh, global variables in modules have to be declared with var etc in chrome, but firefox and safari let it slide if you just assign. Fixed, but I guess I’m gonna have to set up a test suite
- nightpool 3y agoWeirdly I see that changing the "Projectile" selection to "P3" and then back to the original "P4" made the range drop way down, even though the new value was identical to the old value. But changing the "Main Axel" value made it jump way back up: https://imgur.com/a/boo5Xw3 https://imgur.com/a/boo5Xw3 So maybe some kind of "non-functional"/reused state issue exists regardless?
- QuadmasterXLII 3y agoOh, I don’t like the look of that. This may be a valuable lesson in “I should have just used a framework”
- WorldMaker 3y ago> 4. Observables (Ember, maybe Angular 2+?) Don't forget Knockout which was the OG. You can also make the case that Svelte, Vue, and Qwik all are different takes on Observables (at least as much as Angular 2+ is) all with more or less magic and more or fewer escape hatches from Observable best practices to imperative(-looking) code. I got a "What if we did Knockout but with with the compile-time benefits of TSX and Pure RxJS Observables?" itch a couple months back and have made some wild progress on it. I certainly don't think it is ready yet to advocate as an alternative to React, but it's probably in an interesting A4+B2 tangent on your map right here, and I find that interesting.
- jeremycarter 3y agoI remember 2012, ASP.NET MVC Razor pages, combined with individual page knockout Js. Actually worked quite well. Infact that system is still running for that company. Sure we could have made a angularJS 1.0 SPA at the time, but knockout meant we only had to apply the pattern to the pages that needed it.
- WorldMaker 3y agoI even used Durandal some in those cases where we really did want a SPA, but Knockout was good enough. That was something I appreciated about Knockout too was that the SPA framework was around it, not a part of it or implemented inside of it. Same with routing frameworks like Crossroads.js if you wanted something lighter than Durandal for just boring hash-navigation somewhere in the boundary spectrum between full SPA and MPA. It was something that was also attractive about early React that React was similarly just a view engine and could do MPA or SPA or things in between and it didn't try to have the full kitchen sink. I don't know exactly where React stopped being that, but it always feels harder to argue that current React is "just" a view engine. In the larger context here with this article, libraries that are just view engines should be great for building the internals of Web Components. (I'm hoping the view engine I've been working on might serve that role well, though with a dependency like RxJS I'm not sure if it would be towards the top of the list for many developers. It will certainly feel bigger than Lit, for example, no matter how well it tree shakes.)
- 3y ago
- pcthrowaway 3y ago> (B) Advocate a framework other than React that uses the same pattern as React, but improves the usability. I think the two places there is the most room for improvements are: > 1. Animations > 2. useEffect() in general I'm not normally one to "shill" a web framework, and I still mainly use (and love) React, but I'm curious if you've tried Svelte, because it definitely manages animations better than React, and has a different idea of state that's more ergonomic for many use cases (though I won't go so far as to say it's definitively "better" than useEffect)
- Vinnl 3y agoTo add to that, one of the (largely justified) criticisms of React is that it, or at least the way it is commonly used, can have negative performance impact, and thus negatively impacts user experience. However, user experience is broader than just performance, and critically also includes that the application has as few bugs as possible and works well in the first place, and I feel that the model you describe greatly helps there, and it makes unit testing and strict static typing feasible to boot. (Admittedly, these benefits haven't been thoroughly researched, as far as I'm aware, so it still mostly relies on gut feeling and experience.)
- techpression 3y agoI would say SolidJS does everything better than React while keeping with the same general mindset. React spent way too much time worrying about DX to the point that now DX is really bad. Fine grained granularity is such a breath of fresh air to work with after the very large and very heavy brush that is the React “render the world every time anything changes” method (yes they try to be smart about it, but so far haven’t succeeded, the next compiler might solve it, but then we’re back to a black box of incomprehensible code soup to debug).
- vmfunction 3y agoThank you. Finally someone mentions Solid, it got all the good part of React, and none of the bloated parts. Personally, JSX is the mainly thing that makes React attractive. As JSX is just modern E4X. It really ought to be put into the ES standard again instead of this Web Component stuff. Another good JSX implementation (SSR) is: https://nanojsx.io https://nanojsx.io If you just want something light JSX, then this seems the way to go for now.
- wayfinder 3y agoI have to disagree. It can't be that that design pattern because React did not invent it. Every server-side templating library is a pure functional transformation of application state. I can tell you that many people also ported that design pattern to JS. What tripped library writers up is once they applied that pattern to JS, there is no way to actually define the transformation because to do that, you either write a template or the code-equivalent (i.e. using DOM as your data model). And that's where JSX came in. Also, I think you have patterns completely confused. Backbone is NOT in the same class as jQuery or React. Backbone is more like Redux, mobx, or React hooks because it's a data model library. In Backbone, you define "models" and "collections" -- basically, you use Backbone to store your application data in memory. Backbone did have a views component to it but it actually could not generate any HTML. Look at this example from their docs: var Bookmark = Backbone.View.extend({ template: _.template(...), render: function() { this.$el.html(this.template(this.model.attributes)); return this; } }); It literally has jQuery and underscore.js! Backbone had no templating/HTML generation ability so when you used Backbone, you combined the fat Backbone classes with whatever horrific HTML-generation method you used to create a huge monster. You can actually use Backbone.js with React since they are not in the same class. You would not, of course, because mobx is basically the same style of data modeling as Backbone.js but with almost no boilerplate.
- TheHiddenSun 3y agoSolid.js comes to mind - not a framework, but a library - can do fine gained state updates without unnecessary re-renderings (reactivity) - uses dom instead of vdom to produce best in class SPA performance - uses jsx like react Performance claim / proof: https://krausest.github.io/js-framework-benchmark/ https://krausest.github.io/js-framework-benchmark/
- gitaarik 3y agoThe reason React uses a virtual DOM is because when React started, there were no (advanced) HTML templates yet. And it made it easy to setup listeners on elements, instead of manually adding it with `addEventListener()` and possibly remove them again with `removeEventListener()`. So the virtual DOM was really a game changer. But Lit templates solve these problems in a more browser integrated way, without the need of a virtual DOM. How you manage the state is free to your choice, that is also not something exclusive to React and your favorite pattern can also be used with Lit. I wrote a tiny state management library (LitState [0]) which makes it very easy for multiple components to share the same state and stay in sync. I personally find it much more convenient and cleaner than any other state library I've used before. And it integrates very nicely with Lit. [0]: https://github.com/gitaarik/lit-state https://github.com/gitaarik/lit-state
- pests 3y agouseEffect is overused. People use it to compute derived values when that is not its intended use. How many times have you seen the equivelent to a fullname = firstName + lastName inside a useEffect? Its outstanding. :(