Why I don't miss React: a story about using the platform
jackfranklin.co.uk
jackfranklin.co.uk
Honestly, I haven't. The only potential caveat I can think of is when you have some non-reactive legacy code you want to embed inside a React component... but even then React's escape hatches are more than sufficient.
If you're really worrying about when your component renders or re-renders it's probably because there are other issues with your app.
Pros:
* I have generic "zoom/pan" implemented. I did this by making a generic ChartContainer with 5 zones - top, right, bottom, left, content - and you specify just the size of the non-content zones (if displaying them at all) and otherwise it behaves responsively (i.e. CSS style on the container is respected in the internal math). When you scroll the left/content/right vertically, or the top/content/bottom horizontally, it virtually scrolls the other components for you. It also of course handles the math, each area of the 5 is passed a DOMRect describing how big of SVG it can render
* I have smart edge routing component on a graph; if you are doing the math yourself on how to position the SVG elements, you can easily describe that graph, so smart edge routing is free
* my library has themes via CSS vars, and the components written in this way are obviously automatically themed
Cons:
* it's a bit verbose for sure, takes some small time and focus. After the initial investment in ChartContainer though, they work freaking awesome
* D3 graphs often come with sweet animations and such, I don't have any capability to emulate this today, I hate to do performance-heavy things like manually doing math every frame in a hooks-based way, and I don't want MobX in my component library
* you sort of lose access to the D3 ecosystem, nothing is free
To be honest, I think I have made a top-tier Gantt with the smart edge routing and zoom, my Graph looks sharp too, and for overhead views it's super nice to be able to zoom and pan and show rulers on the side (imagine showing factory layout, or a board layout, etc). Otherwise, if you are doing more traditional pretty eye-catching stuff, it's not quite meant for that approach
You may want to check out this library: https://airbnb.io/visx/ They converted a ton of d3 features into proper React components
"They're smart enough to know they're not smart enough to build perfect abstractions, so they do a great job but leave escape hatches just in case"
The interest in Elm took a major hit after the compiler banned use of JS.
React on the other hand can wrap a JQuery calendar in a React component and from a programming point of view, using that component you would be none the wiser.
Also ports force everything to be async - and I am not talking just promises - I mean a new render per call response! So calculating 1+1 on a port requires generate a new render, and intercepting the result in a Redux-style handler, bubbling that into a component.
While you won't need to do 1+1 via ports, you might need to use a synchronous web-api feature that has not been ported to elm, or even use a math package to multiply some matrices.
- Models state as an arbitrary DAG
- With arbitrarily deep dependency chains
- Which may trigger dependent nodes based on only subsets of their state
- Based on computations of arbitrary XPath expressions, sometimes containing non-native extensions; these can be expensive whether implemented as a hybrid wrapper around native XPath or fully in userland
- Which in turn may trigger recomputation of their own dependent nodes
A naive implementation of this according to the algorithm you described will cause real world usage to block sometimes for several seconds until the app becomes responsive again.
Being able to have greater control over when to commit state and when to render intermediate state are crucial to usability for this app. Being able to defer the entire computation for state without a path to an associated view is even better. Being able to batch state -> render updates based on priority even better still. All of this can be accomplished with React’s APIs, but it certainly wouldn’t be the default behavior. And it’s all from a real world use case where SolidJS—which has a similar DX to React but significantly better performance, and which I’ve been prototyping for gradual adoption—also needs more optimization than its dependency tracking alone can achieve.
Even trivial demo apps with well designed pre-hydration state (note: already optimized beyond the default) and otherwise find performance at runtime can suffer significant lag between LCP and TTI by running far too much code for stuff that’s nowhere near needed for immediate interaction.
Granted in most cases this tradeoff is reasonably acceptable. In many cases it’s not. Prematurely optimizing it isn’t a great idea, but there’s a wealth of room for optimizing when it’s valuable to do so.
Mobx [1] is pretty good for this, it batches updates that happen, making rendering more efficient.
Also regarding rendering, react will update a component it it's state changes. It might update its children components, but if you pass them in as props, they won't be updated, as they're rendered in the parent component's context.
This allows you to create complex applications with thousands of interactive components, and have quite good performance, as minimal rendering is performed.
Oh, so like every JS interface ever. :D
>You just have to know how to use it, and when not to.
So, you have never had a JS application delivered over the web become unusable despite your attempts to only use it how and when you need to?
Okay, well, congratulations either or in order or you've not been forced to use it for something you didn't want to or have just never been building something big with the technology and made a mistake?
I mean my stuff generally doesn't become unusable, but generally is not always.
Of course I have, that’s not the point I was making. My point was that JS and the VMs it runs on are very fast, if you know how to use the language and when not to use it. That couldn’t possibly apply to apps you didn’t build. If I’d said C or whatever is fast if you know how to use it, I don’t think I’d get this comment about some horribly inefficient downloaded printer driver.
could be using data returned in XML format because there is no JSON endpoint for that particular data source.
XPath is also nice for dealing with just about any complex markup tree, for example if you needed to extract data from serialized DOMs that were sent to your application somehow.
How about SVG tools using XPath?
One of the promises of switching from class-based components to function-based was supposed to be an automatically applied version of shouldComponentUpdate, which AFAIK was never fulfilled.
You've now described the Web Components crusade which, among other things, engages in actual gaslighting.
that's why I prefer Solid instead of React. For client side stuff, Solid is sooo much better than React.
This is totally uncalled for. He's not attacking you. He's explaining a tradeoff, very reasonably.
> I would even say that if this is not a core part of your product, you are simply wasting time and resources.
I find especially interesting that this phrase can be used to defend both sides of the argument. If you are building a highly rich application, chances are that using a framework for that is the right choice, agreed.
But.
Not all the apps being build out there need to be Very Rich Apps. There's indeed a lot of space for only-slightly-rich-but-mostly-static apps, despite the recent HN article.
And for those, introducing a framework is ... precisely, a waste of time and resources.
What? I don’t see how “dislike” would describe anything other than some kind of preference. I don’t see how it’s an attack.
Imagine if I had started my answer with “Since you love frameworks so much, then…”. That would have been a similar mischaracterisation on my part (equally uncalled for, since I don’t know the other person enough to make such judgement)
Also makes it harder to test. There's a great paper called "Naked Objects" which I'd recommend for anyone doing GUIs, but powerful idea I got from it is make your presentation code so immediately obvious from your business objects that you can practically generate it automatically.
It proposes a complete approach of which not all of the parts will be useful for any given project, but it is -very- much worth reading even so.
And yeah agreed, but I think we could all use some scantily clad objects at the very least.
This is a classic red-herring argument from developers who have not built anything complex with vanilla js. You can build rich interactions with or without a framework, you’re just making different trade-offs (conventions, learning curve, flexibility, tooling).
There is a much larger amount of man-hours put into browser APIs, and web components is one of them. I don’t see anything wrong or that warrants a “you’re wasting your time” warning in his argument. And note, he’s talking about the chrome dev tools everyone including the react team use daily, not “basic forms”.
And the fun part is that when you are going with the browser APIs like a responsible developers, do aim for backwards compatibility and browser support and all that jazz you will at some point also be annoyed to write a lot of imperative code to add a modal, add this field dynamically, handle class toggles and make another button somewhere change something else in the UI that it's inevitable that you write a poor-mans version of React that now no one knows how to maintain and onboard people.
React didn't come from PHDs in some university, it came from the real needs and desires of developers to just think in "I want my UI to look like this, get it done" and not in "Aight, I add a class here now, but update the value here, this button also needs to be disabled now and then make the request and if it fails then add this element for the error in this spot and enable the button again but if it works yeah just throw all of these away and replace it with a success message"
Nowhere in the article the author claims web components is a great choice for everything. He works on DevTools, which is not a website, and 100% js already. Seems like a perfectly ok choice.
> be annoyed to write a lot of imperative code to add a modal
I’ve recently added a modal system to a react app using react-aria-modal, and no kidding, it took over 1000 lines of code* to get it working, following their guide to the letter. Later, out of frustration, I reimplemented the same feature using Svelte (which lets you get much closer to plain JS and HTML), with the same features and aria support, in a couple of hours and 10x less code.
> it's inevitable that you write a poor-mans version of React… it came from the real needs and desires of developers
React uses a very specific architecture of VDOM, stateful components, hooks etc. There are plenty of alternatives, including well developed “poor-man’s versions” like Preact, hyperapp or SolidJS.
It seems you’re under the impression React is some kind of universal solution to all frontend apps, developed by “the people”. It’s just a framework, developed at facebook, born from the evolution of their existing server component system. It works, feels nice for small apps, I use it along with a million other people, but it’s not a panacea, and it’s sad that a lot of people simply dismiss everything else before they’ve had a chance to actually understand the trade-offs.
* id say it’s imperative code too - calling hooks in the correct order, passing data from one to another, telling react what the dependencies are, updating and transforming values
Sure, the browser apis are great and always getting better, but I don't see how that's a reason not to use the framework.
The path is littered with the ghosts of frameworks past. Don't let the current efforts or trends convince you that we're done with this process. React will be a ghost one day.
The implication was that we're in a transition like that presently.
It's people that think electric motors are always the right solution to every problem and it's only a matter of rube Goldberging it up to shoehorn electric motors in to places that that's better without them.
It's against arrogant dogmatic rose colored glasses fanboyism being mistaken for software engineering
And this isn't straw-manning, the internet is full of these evangelists that exist as effectively marketing arms, as if they're bicycling around wearing nametags on behalf of the Church of Current Day Frameworks.
All it does is create messy piles of tangled garbage that wastes people's times and gets thrown away to be rewritten when the next flashy thing comes around. It's hot fashion for programming
It's gross and needs to stop. Seriously. Let's build the future, help fix the world's problems and quit fucking around.
This fetishism for shiny things have left us impotent executioners of meaningful change and thus we are amidst the tech stagnation
So did jQuery, and that google framework used to create Gmail, what was it called?
Oh yeah, nobody cares anymore because they're irrelevant in 2022.
Even if the React development team would stop the framework will for sure be around for a couple more years and receive at least security patches.
React has too many sharp edges, it'll only be here until something shinier supercedes it.
I don't find many sharp edges in day-to-day React work. I say this having once been a very strong proponent of framework-less frontends, before trying Vue, then Svelte, and then settling on React.
It’s a mature, stable technology, still in wide use - and not really a competitor with react. That you claim it’s “no longer interesting” says more about your own preferences and ironically makes it sound that you are personally interested in the newest shiny fads - so I’m confused, what is your objection to react then?
Angular isn’t exactly dead - and is a more apt comparison.
I suspect people still reach for jquery for similar reasons. They know it makes complicated stuff work, it’s reliable, they don’t need to think about the specifics of the problems it solves… As a result, they’re less likely to discover that it’s no longer necessary in the first place. They’ll just keep using it.
These mostly come down to
1. It’s no longer the fastest, in fact it’s barely competitive speed wise with many things that have come after it.
2. It’s architectured in such a way that it is fundamentally misaligned with the rest of many web standards (I.e the DOM) which made a lot of sense when it was released but is now a major liability.
3. It now has to ship around a lot of code that now lives natively inside the browser and is now rather bloated as a result compared to newer iterations such as Lit as mentioned in the article.
Personally, I think it’s fatal in the sense that they have painted themselves into a very specific corner with no obvious engineering solution to get them back on the standards path. Its problems as a result aren’t really fixable without major architectural changes that would fundamentally change the project. On top of that they are only going to get actively worse over time as more things get moved into the browser and they are still stuck shipping a bunch of JS code to do the same thing. In short they are on a bad long term path with no clear off ramp.
I wouldn’t start a major project in React in 2022 for something I wanted to be around in 5 years from now as a result.
Edit: 3,700,000 downloads per week on npm alone. That’s not a complete or perfect representation of usage, but that’s a significant number
And this isn't an issue of me not understanding React or hooks, I would consider myself to be as expertly acquainted with hooks as it's possible to be.
Now, do I still use React for everything? Yes. Do I prefer hooks to class components? Also, yes.
Okay I can criticize React and its weird solutions until the cows come home, but this is a pretty weird one because it’s entirely an implementation detail. No one working with Suspense ever needs to know that’s how it works unless they’re building a library to be compatible with its behavior. Otherwise it’s just trivia.
Admittedly, I haven't tried debugging React 18 yet, so I don't know if that actually happens in practice.
The programming paradigms I like best are declarative and make invalid or undefined behaviour impossible to represent. Hooks do the opposite: they're procedural, make it very easy to write a program that compiles with subtle errors, and don't have compile time checks to stop bad code.
Hooks are called every render, which is a relatively transparent process that happens all of the time. All hooks have to be called every render, otherwise you're breaking the rules of hooks. The reason why is because the only way hooks know which hook they even are, is the order in which you call them.
For example, if I have
const a = useRef(true);
const b = useRef(false);
The only way react knows that the first value it should return the next time it renders is what I'm expecting to be value `a` is because that useRef is called first every render. These are all kinds of rules and assumptions about hooks that make them not behave at all like normal functions. I don't think people understand that, for useRef, for example, those two lines of code are run every render, passing in the initial starting values, which then react disregards after the initial render, and maintains a mapping of ref and state and memo etc values all by the order the hooks are called in. I see people use hooks in callbacks all of the time and just fundamentally not understand that they're doing it wrong.Then there are all of the closure problems with useEffect and useCallback that I see people really struggle with.
And useState...lordie. The fact that it defers setting the state value, whereas useRef will immediately have its value updated. Deferring useState has caused so many bugs.
A similar thing happened to CoffeeScript: no one uses it anymore because nearly all of its good ideas made their way into JavaScript itself.
My opinion of each of those parts has been primarily down to the developers, not the underlying choice of framework.
Things that work in production last.
I still see it on resumes today.
> that google framework
Seriously, Google stuff is infamous for being smothered by Google itself, what's your point
> nobody cares anymore
Literally the only non-Google example you could think of is still popular. But jQuery wasn't a graceful idea with a strong implementation, it was a wrapper to alleviate the pain of browser APIs. React is a wrapper to alleviate the pain of JS. Thus my original claim: "[a] world where React isn’t used and remembered is one where the web isn’t based on the same primitives". I don't see that happening soon.
Web components were proposed 11 years ago. Widely available for at least six. When will it stop being "early days"?
Now all the air in browser development has been sucked out of the room by them. Instead of actually moving the web forward browsers are busy patching holes and problems created by web components because they are horrendously badly designed.
And they still have an issue list as long as the equator. Any framework in such a state in "early days" would be laughed out of the room.
Custom Elements weren't available until 2018. So unless you are referring to the chrome-only experimental v0 version, I don't think you can say it has been widely available for more than 4. And there will likely be substantial improvements to it before it starts dominating web development.
Yes, my timeline was off.
> And there will likely be substantial improvements to it before it starts dominating web development.
I'm definitely veering away from my original statement, but here goes :)
There won't be any substantial improvements in web components. It's painfully obvious how many shortcomings they have, and how many holes have to be patched before they can become actually useful. I mean, they had to come up with a whole new Javascript API just to make them participate in forms.
And now their existence taints and poisons most other improvements to the platform. For example, Scoped CSS (which on its own would solve a huge chunk of what web components offer) now have to be twisted to accommodate web components, and will likely be a worse spec as a result.
Chrome "developer advocates" will incessantly berate and gaslight other projects and frameworks, and will claim that web components are a success because companies with billions of dollars in revenue and thousands of developers use them to create a yet another avatar or breadcrumbs component. That... that is neither success nor a path towards any substantial improvement.
"It's almost as if congealing 2010-era best practices in the platform before we'd finished exploring this territory was a mistake" [1] And the future is likely to be component-less [2]
If the tens of millions of dollars that Google alone has poured into Web Components had gone into something meaningful like https://open-ui.org we'd have a significantly better and a substantially more future-proof web. Alas.
[1] https://twitter.com/Rich_Harris/status/1513668040784814084
[2] https://dev.to/this-is-learning/components-are-pure-overhead...
Not saying it will never go away, just that, maybe the front-end world has finally, significantly slowed down in churn. Things could always be better (Svelte is nice) but overall, React does what I need and I rarely curse at its design.
From jQuery’s release to 2014 there were multiple phases of front-end frameworks.
Backbone, Knockout, AngularJS, Ember. All of these had their time in the light during that phase. Most companies were already switched over to one of these frameworks. React was the new kid on the block at this time.
You Don’t Need jQuery was out well before 2014.
It’s also a bit difficult to compare jQuery since it’s a library that can linger in a codebase indefinitely. It’s not a framework.
Also jQuery release date was 2006, so the equivalent year 9 would be 2015. By which point React migrations were in full swing. I wrote my first on the job React + Flux application in 2014 and then joined a new larger company in 2015 where we were making plans for a React migration.
Unless I'm selling a render solution, I don't want to be maintaining a render solution. Maintaining glue code might suck, but writing everything from scratch limits the scale of the work that a person can accomplish. I liken it to polishing gears rather than driving the car.
In my experience, it hasn't seemed all that significant. These frameworks are absurdly general and cover a range of use cases and deployment methods that most people don't use. I just need the kitchen sink, not everything else.
So far, just using custom elements and a small wrapper around the <template> element, I've not been struggling to create the features I need or would otherwise miss.
Also, the trend of hiring <framework> developers is a plague: if you know JavaScript and the DOM well, learning the basics of react is a couple afternoons of work and you can figure out the pitfalls via code review and learning on the job.
But generally I wouldn’t be worried about onboarding a web dev who doesn’t know the lib, it’s not rocket science. One of the appealing things is how very straight forward and clear it is.
I am currently working on an app at work that wants SPA functionality, but they won't let me use any of the frameworks. Tons of vanilla JS and Jquery. I am sure what I have written is probably considered a crime against humanity in some place.
Does it work? Yes. Is it an elegant and maintainable codebase? Not by my definition.
I’m thinking you could have a single file, jQuery-based, hand rolled version of some framework and get many of the benefits while still technically complying with the “no frameworks” rule. In the same way that you could reimplement Redux easily if you for some reason weren’t allowed to use it.
I suspect diffing performance would be the bottleneck but I wonder if you could come up with some weird half solution that worked for your particular use case.
I've not used Redux for anything before, but I will look into for sure. I've heard the name thrown around a few times on here, and I could probably use something like that. Just nothing that would require a staunch learning curve to use.
I doubt I will be able to roll my own version of whatever these project due mainly because of time constraints and because I am the only developer working on it. Since we have adopted all the Agile stuff, Sprints are basically deadlines and not very...Agile.
I've built my own framework once out of frustration, thinking typescript will make it easy... after a while I realized that I was just rebuilding chunks of existing frameworks and most likely not in the best way. Webtech is really messy to begin with, typescript didn't really save me. So I stopped. Sure it was nice to know how to build your own viewstack, navigation and state management and how to some newer html5 features, but it really was not the way to go. Vue js seems to be closest match to the way my mind works and built a very crippled version of it minus all the good tooling and plugins. I was also influenced by Knockout and Wpf/C#, so it had some similarities of what I used to do in those. I honestly do not like the way react works or the way it wants me to work, it feels extremely messy too (syntax and project structure)! I get the same feeling from react that I got from own crappy framework!
So anyone reading this, I encourage you to build your own frameworks, but think very carefully if you need it in production and can support it in the long term. Try to keep emotion/ego out of the decision.
> I'd definitely recommend using a library for this, and we settled on lit-html (link to library from npm)
This article is mostly about switching from React to Lit. You can use modern web APIs (like FormData) with React, FormData's not a replacement for state management.
You can use Web Components with React, the way Fluent UI does (https://docs.microsoft.com/en-us/fluent-ui/web-components/in...).
In this single case they replaced a couple validation functions with attributes. Good to move that direction but if that's all you use React for then yeah, you might not miss it much.
I kind of feel that given the "simplicity" of a single class wrapping custom elements, everything is pretty boring.
Note: I cannot do better.
I don't use lit-element, it's too heavy for me.
lit-html, on the other hand, is wonderful and rock solid.
I typically do light dom components, rendered with lit-html. Simple classes that extend HTMLElement.
When I want reactive style, I add setters that call render(). When I want imperative, I add class functions.
All my components generally take care of themselves and are mostly encapsulated, they'll generally have a init() method that loads the data they need, and calls a setter which kicks off the render cycle.
Alternately, data will be passed from a parent component via a property, and that'll also kick off the render cycle.
In many cases I do a combination of the two in order to support deep linking.
I'll mix and match design systems sometimes, depending on the payload weight. Ionic, shoelace, etc...
The Vaadin router ties everything together beautifully.
I also have a small state utility called ApplicationState[1] that I use for the edge case of cross-component communication and triggering. It provides a graph-based approach to notifications/state change.
I've been using this approach for several years with success, with deeply complex and large applications and small lightweight tiny footprint apps.
I think FAST is dead because MS doesn't want to play keep-up with it. In fact, all of the component libraries that Lit advertises on their home page (https://lit.dev) seem be Thanksgiving leftovers put out on a buffet. No one is seriously updating a set of web components for public use.
But... perhaps that is because Lit isn't really great for making components for others? It doesn't get you out of the work of documenting them, for example, which is already done with canned component libraries. It certainly puts all the fixes back on you.
In my experience, Lit is terrific for green sheet projects and ones where you can keep everything in-house. But there is no "Lit community" or resources for people getting into it who want a jump start. And no great tutorial doc.
Unsurprisingly, you don't see Lit discussed too much anywhere!
I'll freely admit I'm a backend guy and don't know much about JavaScript frameworks, but the author emphasizes they didn't use Lit, just lit-html, and for the same reasons they didn't use React.
Is lit-html really such a huge portion of Lit that you disagree with their own assessment of what they've done?
I think how they gloss over the "we'll just write a library to handle component rendering, lifecycle and state" portion as a "basic scheduler" is a bit disingenuous. The author even mentions they are essentially recreating some features of React, but felt it was worth the tradeoff.
You'll also be writing any kind of routing or other validation tools that you need. Which is actually glorious! You get to make one that's small and easy to keep in your own head, yet flexible enough to be extended and expanded in any way that you can imagine.
There isn't a React component that would have helped me build this game[0], other than very basic stuff like buttons. But with Lit, I could write components all they way down to SVG graphical elements and create all kinds of new behaviors that React doesn't understand.
[0] https://hexxedgame.com (100% Lit/TS)
Care to expand? (I'm working on SVG-as-React-component stuff.)
I don't know any project in JS-land that is more serious about semver, backwards compatibility and reliable upgrades than react. If facebook dropped the project tomorrow, Vercel alone could probably continue to maintain it well.
Facebook made React like this because of these requirements: they wanted their chat application that requires various real time small updates to multiple parts of the page to run quickly where a wipe and rerender approach is too slow, while being declarative because their constantly rotating staff had trouble writing it imperatively.
To meet this requirement you need:
a constantly revolving staff that are of varying degrees of competence and can't write non-buggy imperative code in the few situations you can't just wipe and re-render
a situation in your application where wipe and re-render is too slow, AND the situation is too complex to hand-write the individual updates manually
The other decision React made that was wrong was the need for JSX. They decided on JSX because they made a mistake many people make when just using the pure JavaScript API for creating components - they tried to make it nested like html using a fluent/chained call approach. As it turns out, trying to keep the nested HTML structure is not necessary for readability.
My library is github.com/thebinarysearchtree/artwork
After using it, it makes React look like SOAP vs JSON. It has less code, runs as fast as you can get, and everything is in your control because it is just web components with some functions to handle the repetitive parts.
Personally I prefer mithril or Soild over all other front-end framework. They light and fast. And Mithril author had in depth knowelge of the other frameworks.
This is interesting -> this is the best thing in the world -> here’s how this could be better
The “use the platform” people have been making this case for web components for at least 5 years now. The reality is WC will take off when and if they are a better alternative and even then they’ll need to be paired with some sort of framework. They may even make their way into React one day.
The only thing that bugs me about these takes is React is using the platform. It works great in all major browsers, it’s not some extension like Flash. It’s the platform.
How do you debug?
Note: I say this as somebody who really rather loves react+mobx - but you're not wrong about the trade-off.
> Replacing lit-html would be an undertaking but much less so than replacing React: it’s used in our codebase purely for having our components (re)-render HTML.
That's high praise. I might take a second look at Lit and style it facilitates.
Don't use it
[0]: https://github.com/curlywurlycraig/vdom-util/blob/master/src...
If the thing you're integrating is an evolving, improving moving target, and it's coming out of a team of only a handful of people, double any visible costs associated with your application for the sucker who must build it in 2 years time to add some new feature. It is possible to build a strong and easy to communicate case for avoiding frameworks using long term maintenance costs as the basis.
jQuery was actually pretty good at this, it only had one big flag day that I can remember. In that sense, jQuery was much closer to what you get for free working directly against the platform interfaces. Deprecation cycles are much, much longer, and burden of proof much higher for new features in the browser than pretty much any third party framework.
Somewhere here on the thread there was slander directed at Closure Library / Compiler. In this context, that is so totally tone-deaf, Closure Compiler/Library projects from 2010 still build with little to no changes today (based on local experience). I can't say the same for any alternative I have used in the past decade.
React is over 10 years old and is backwards compatible probably all the way back to its 0.x versions.
Web Components have already deprecated and removed v0 of Custom Elements, and deprecated HTML Imports. On framework/library side: Polymer 1 wasn't compatible with Polymer 2 IIRC, and then Polymer was scrapped and discontinued in favor of lit.
React is a surprisingly safe bet for durability.
Probably worth looking into again.
I also concur with the author about lit-html. It does one thing and does it really well, easy to understand, and no transpiling needed. Can't recommend it enough for generating dynamic html client side.
One issue I have with lit is that it just forces you to turn everything into a web component instead of a carefully deliberated choice.
Honestly I just like the idea of making my own HTML tags and being able to do more with markup.
1. Need to be configurable
2. Are meant to be used many times through an application
3. Are not easily built using regular html
For point one, take a loot at input[type="text"] html5 elements for instance. Placeholders, validation, size, stylability, errors.
Similarly, the video tag. Volume, play pause, size, quality, playback speed, compatible formats, much more.
For point two and three, you could for instance make a Login component, to encapsulate your authentication form into a component, but this is easily achieved using regular html forms. Also, you're most likely only going to use it once or twice.
So what are good examples?
A sparkline component, this is a type of an inline graph.
A markdown or html editor component.
Custom interaction or input components. Consider for instance where you're working on an audio mixing application. A rotatableKnob element is an elementary input here.
They are both forcing the usage of custom events to dispatch functions and share data between components. It's horribly unergonomic. Using the DOM with event bubbling and capturing feels really bad.
Orchestrating rendering is a mess.
The Shadow DOM and templates don't really solve any issues that aren't already solved with things like CSS modules for style scoping and even using element cloning is faster than templating.
The only thing they have going for it is that they're a nice way to share 3rd party components as an alternative to iframes or JS library API which targets a DOM node with a parameter.
And you can use any small framework like Preact, Svelte or SolidJS and wrap it with a web component.
Then I'd use something like https://github.com/preactjs/preact-custom-element, https://stenciljs.com/docs/custom-elements or https://github.com/solidjs/solid/tree/main/packages/solid-el....
As far as I see, there is nothing that WCs provide which isn't already solved, in a better way, both for devs and users.
And making a framework that use custom elements and shadow DOM for component-based logic and encapsulation seems like a purely philosophical approach to adhere to some vision of "platform purity".
Honestly once you get used to it, it becomes second nature... For me at least.
One piece of advice I would give is to not try to ram the hooks use-case into things. It becomes especially annoying when you're dealing with asynchronous values, where you need to deal with 'null' and friends. Sometimes some imperative code in useEffect is simpler to read and easier to maintain; it's fine to step out of the paradigm for some things.
Author also talks a lot about the issues with losing control of the component model when using preact
Are these now useable on any contemporary browser? Or do you use some kind of polyfill? Anyone have a good from-zero tutorial for the approach OP is talking about?
They can also maintain a “shadow DOM” with its own HTML subtree and CSS scope, so that you can make complex elements whose internal state is encapsulated from the rest of the DOM.
Web Components are just a part of that platform, and very badly designed at that. A lot of the platform around them now exists only to patch holes in them (like form participation) and to solve the problems they introduced.
And since they are now a part of the platform, they poison everything like upcoming CSS scoping which instead of being a straightforward thing now has to account for all the web component insanity.
Edit. There also so many thing wrong in the article that argh.
"We don't need React and dependencies"... and then talks about lit-html which is a small framework with custom syntax and constraints on how you can use tagged literals.
"Easily replaceable dependencies"... and again talks about lit-html which is a fully incompatible replacement for Polymer. I wonder how folks that used polymer (Youtube) feel about "easy replacements".
"Can't control rendering with React" and talks about Web Components which literally give you no control over when a component can be rendered, don't have lazy loading, cannot subclass SVG or embed partial SVG etc.
And so on and so on...
lit-html is completely different from web components and not meant to replace Polymer. lit-html is a library that just handles rendering and lit-element, which is meant to replace polymer uses lit-html as its renderer to make web coponents.
React is also just a library that handles rendering. But sure, "it's different".
I promise you'll love it if you're switching from React (pure HTML, CSS, and JavaScript w/ minimal abstraction). And it's full-stack so no more stitching together frankenstacks. Good ol' isomorphic JS for devs who value their time/productivity.
W3C standardized Web Components before React existed and took off, unfortunately. I expect the next standard to just be React itself (or a barebones version that the library can build on top of), patent licenses permitting. I'm pretty sure as a C++ precompile, it would be unstoppable and end the debate for good.
> To re-render, you have to manipulate the innerHTML--usually replacing the string every update
"Usually" is relative, I guess, but nothing's stopping you from using the imperative DOM APIs to update the component's contents; I daresay this would be the typical thing to do. These APIs will be just as performant as anything else out there. What you're really giving up, then, is the reactive programming model. Web Components are just a way of modularizing things; they have nothing to say about how you update the DOM (for better and worse).
You are right (I think) that there's no good way around converting attributes to and from strings, though the performance overhead there should be minuscule in most cases. The bigger problems with that are a) some data (like functions) can't be serialized at all, and b) it leaves a lot of room for passing invalid values
This video is a few years old, but the core concepts remain the same.
They are not concatenation by themselves. But for them to be useful, you will end up doing a lot of it because there's nothing else to do with strings than parse (often with regexps [1]) and concatenate [2] the strings. And then you dump the concatenated string into the DOM using `.innerHtml` [3]
There's no magic.
[1] https://github.com/lit/lit/blob/main/packages/lit-html/src/l...
[2] https://github.com/lit/lit/blob/main/packages/lit-html/src/l... and https://github.com/lit/lit/blob/main/packages/lit-html/src/l... and so on.
[3] https://github.com/lit/lit/blob/main/packages/lit-html/src/l...
Any property can be a full JS object. When the property is changed, it is re-rendered in your component. I have never touched innerHtml and my Lit apps pass and render all kinds of stuff into html`` tagged templates.
It's really pure magic because you can freely mix regular old HTML and regular attributes with dynamic data and data binding. There's more than one way to write anything which gives you great flexibility. I adore tagged templates, and they work for CSS and SVG, too.
I'm talking about how lit is implemented internally and that's why I provided links to relevant parts of lit's code.
People having no idea how things work is the bane of our industry. And that's why we have objectively false statements like "regular old HTML and regular attributes with dynamic data and data binding".
Lit is almost as far from "regular old HTML" as React's JSX is: lit is a HTML-like DSL that even has constraints on how you use tagged literals themselves.
E.g. `<${tagName}></${tagName}>` is a valid tagged literal and it's invalid in lit.[1]
> they work for CSS and SVG, too.
If lit lets you mix SVG with custom elements, they don't really use custom elements. See discussion https://twitter.com/Rich_Harris/status/1198339672361119745?s...
[1] https://lit.dev/docs/templates/expressions/#invalid-location...
Are you suggesting that Lit is updating .innerHtml when it doesn't need to? And are you sure about that? Because that should be entirely under my control by setting properties or state of the component, not by Lit redrawing them willy-nilly.
Literally nowhere did I say that. I was responding to a specific thing.
How is it "objectively false" that Lit mixes regular HTML with data binding? That is exactly how it works. I have several Lit apps and they use regular HTML as well as custom components and both have access to Lit properties and state that are dynamic.
Are we talking at cross-purposes or are we trying to say the same thing two different ways? I use this tech every day and I feel like you're saying something about it that's not true -- or maybe I'm not understanding your view.
I never said needless
> that "string concatenation" is the only thing they can do
It's not what "they" need to do. It's what you, or the library using them needs to do.
> Now we are agreeing that that's not true
If you invent something that I never said, then yes, we can both agree it's not true.
> How is it "objectively false" that Lit mixes regular HTML with data binding?
Once again that is not what I said. The objectively false statement is that it's "regular HTML". Lit is a HTML-like DSL because none of this is "regular HTML" because those attributes are invalid in regular HTML:
html`<div ?hidden=${!show}></div>`
html`<input .value=${value}>`
html`<button @click=${this._clickHandler}>Go</button>`
And, on top of that it even adds constraints to tagged literals themselves: // Valid JS, and valid tagged literals. Invalid Lit
<${tagName}></${tagName}>
> Are we talking at cross-purposes or are we trying to say the same thing two different waysNo. You're inventing things that I never said or implied and arguing against those inventions.
You can definitely mix data binding with regular HTML. It might be "invalid" according to a spec that makes no difference. The point of all of this is to write apps that work and can be debugged.
What is the rallying cry against Lit, exactly?
Please re-read what I wrote in my very first comment
> What makes you say the .value and @click attributes are invalid?
Just checked the spec, you're right they are valid. Hm, I was sure they weren't. Won't dig through the history to see if this changed :)
However, "Authors must not use elements, attributes, or attribute values that are not permitted by this specification or other applicable specifications, as doing so makes it significantly harder for the language to be extended in the future.", https://html.spec.whatwg.org/multipage/dom.html#elements
So I'd say they are still not okay on existing HTML elements
> It might be "invalid" according to a spec that makes no difference.
That is a very bad stance to take. "Invalid to the spec, but who cares".
> What is the rallying cry against Lit, exactly?
There's no rallying cry against lit. Stop. Inventing. Words. And. Meanings. I. Never. Said. Or. Implied.
There's a single very literal comment I made with links to support that statement.
I'm out of this discussion. I have other things to do with my life than keep saying "I never said what you think I said" over, and over, and over again.
Is this actually how people pass props with Web Components? I've only used web components for a few years but I've always created a new instance of the class and I pass props using the constructor like:
`${new ExampleComponent(props)}`
Then in the constructor it's just this.state = {...this.state, ...props}
Boot up, runtime, micro benchmarks and at scale.
One of the core values for React for me is simply code structure - organising things into a hierarchy of elements seems to make sense - I found that hard to replicate when I once tried to build a vanilla js application.
In Lit, there are *no* pre-built components. No boxes or buttons or controls or routing. None. You make what you need.
Sounds daunting but, as the author points out, it frees you from cruft. You make only what you need. YOU design the API and syntax. And you add/remove whatever you want, whenever.
It would be hard for me to go back to canned components after Lit! Try the interactive tutorial:
I wish there were more details about this. Implementing a small scheduler seems like a monumental task and I'd love to learn more about how to implement a base-case.
- `jobs` is an array of functions
- enqueue adds a job to `jobs` and starts running jobs if not running
- job running can be triggered by animation frames or setTimeout
It got me thinking, why these frameworks make simple things difficult?
Note that I am a backend/infra engineer (but I am able to build complex web app using jQuery back in the old days.) so I may be missing something here.
So stuck with iframes which although I can hide to some extent, are terrible.
We now use a JSX renderer that emits plain HTML strings.
You get all the ergonomics, the IDE assistance of checking for typos in your attributes, ensuring your closing tags line up, and webpack can flatten it back to plain HTML at compile-time for no run-time __jsx / React.createElement() calls.
> It is not a call for everyone to immediately drop React and move to web components.
> It is not a blog post declaring React “dead”, or the wrong choice for every project.
> It is not a blog post declaring web components the best solution to all projects.
You might want to consider how well the phrase, "Haters gonna hate," applies to your comment.
What does using Vanilla JS look like? Here's an example: https://github.com/wisercoder/eureka It uses two tiny 500-line libs. It uses TSX files, just like React. It has components, just like React. It doesn't have incremental screen update, but neither does React, if your components are interactive and stateful.
Do you have any concrete examples for this? I'm not sure I agree: I've made plenty of stateful components in React and they are just fine. If anything, they're a lot cleaner than what I could do in plain JavaScript, thanks to the framework.
Further, could you expand on what you mean re: recommending changing the key? I have never heard the React team suggesting to do this, although maybe I missed something in the documentation :-)
I've only need the "change key to flush components" trick very few times, and most of those where rush fixes for bugs that had a better "doing it right" fix at a different level.
If you instead are talking about syncing props with state, there are ways to do this as well without changing the key, but this is considered an anti-pattern in the first place.
This sounds more like bashing react without even knowing it very well in the first place.
"If your component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result."
It will correctly keep your scroll position, caret position, etc. if you use React the way it's intended to be used, which is very easy to do and learn. Of course if you use the `key` prop to blow away the entire DOM with every change all these benefits are lost, but thats not react's fault, its your own.
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-d...
What the author is trying to convey is that using getDerivedStateFromProps is not the best idea, and there are two simpler ways of doing it. The first solution (only keeping the state in one place) is the better one.
About the solution you're repeating all over the thread, anyone using React will notice that the "key" change solution you're talking about only works for trivial cases: it doesn't work in practice if you have more internal state in the component. It does work perfectly fine if you only have one single piece of internal data.
This is of course a past worry. All this is much simpler to solve by using Hooks.
But the important lesson here is maybe that one shouldn't judge whole Frameworks by advanced articles about edge cases written 4 years ago that require more experience with the framework than you have.
All of this complexity is completely unwarranted, which is the point of the article at the subject of this thread. You can do it with simple vanilla js and it is easier. Javascript developers tend to buy into frameworks too easily without realizing the framework is making some things more complicated than without any framework.
No, it isn't. This is a ludicrous statement.
Replacing the key will RESET the internal state of children objects. Meaning you can't use this workaround for any component that has any kind of internal state does not come from props.
See for yourself: https://codesandbox.io/s/compassionate-williamson-qezsw5?fil...
On the other hand, it is completely trivial to update props that don't affect internal state. This article is only about updating props that affect internal state of components that don't have any other internal state.
> All of this complexity is completely unwarranted
No. All of this complexity you're complaining about exists for one very specific edge case, and this edge case exists in non-reactive frameworks too. You're just extrapolating the complexity of one single edge case to the whole framework.
> React works well for simple, non-interactive components. Complex, interactive components are going to have state. Stateful components don't work so well in React
React components are designed with state in mind. When state changes, components passed that state in the form of props are re-rendered. Don't take my word for it though, from the first paragraph on the reactjs.org website; "React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes."
> At the point all of the benefits of React (preservation of selection, caret position, scroll position etc.) vanish.
I have never heard these spouted as the benefits of React. The main fundamental philosophy of React is that only components that have state changing "react" to changes - in other words, the benefits of React are: no unnecessary re-rendering (hence the virtual DOM).
> If you want to update props in a stateful component, the recommendation is to replace the component entirely by changing its key
This part just threw me, if you are doing it this way - you are doing it wrong.
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-d...
> I have never heard these spouted as the benefits of React.
You will find this if you read enough of React developers' blogs. JavaScript and DOM these days are fast enough that most pages can completely re-render the page and replace the whole DOM in one shot and you won't be able to tell the difference. The downside of doing that is that you lose focus, selection, scroll position, etc. So preserving those things is the benefit of React.
They work fine, though managing state outside of components via a state management library is common.
> If you want to update props in a stateful component, the recommendation is to replace the component entirely by changing its key.
Where do you find this recommendation? I’ve never seen anything like it, and keys are usually only used for repeating sets of elements, and you would generally only use a different key if something is not the same logical entity as the thing that previously had the key.
There might be some cases where you want to force a new rather than updated component by the kind of key manipulation you describe, but it's not the general case of prop updates for stateful components.
> It doesn't have incremental screen update, but neither does React, if your components are interactive and stateful.
React does have incremental updates for interactive, stateful components. You can deliberately negate it the way you’ve described, but you should not, generally.
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-d...
> keys are usually only used for repeating sets of elements
Not true at all!
> In most cases, this is the best way to handle *state that needs to be reset*
You are talking about updating state, react author is talking about resetting. That's a big difference.