DEV Community

Discussion on: Why the React community is missing the point about Web Components

Collapse
 
dan_abramov profile image
Dan Abramov • Edited

A few quick points from my perspective. (I work on React.)

  1. We're not opposed to supporting web components better. The problem is that there's no single "web component community". There are multiple subcommunities. You mention "web component libraries" in the post. These libraries don't agree on a single standard so React would need to pick a side in debates like "how does server rendering work with web components". Whatever we pick will have large downstream effects, and our reluctance to support more has to do with being careful (see [1] note below) about the semantics — not somehow being at odds with web components per se.

  2. As I mentioned in the previous point (and you mentioned in the post), there are multiple "web component libraries". As far as I can see many of the criticisms of React would apply to such libraries as well. I don't think the way to counteract "DOM FUD" is to introduce "library FUD". If you're using a library for defining and updating your web components declaratively, you're not following a conceptually different approach from using React.

  3. Saying "you can do everything with WCs that you can do in React" is double edged. Yes, of course, you can do anything — because we haven't actually agreed upon any constraints. If the constraint is "you don't use a React-like library on top" I think you'll find there's plenty of things that are very hard to do with an imperative abstraction like vanilla WC APIs. We've done a few talks about what using React as a unifying abstraction lets us do (such as non-blocking rendering, or dynamically loading UI code without degrading user experience). You might want to check them out (youtube.com/watch?v=nLF0n9SACd4, youtube.com/watch?v=ByBPyMBTzM0). Of course, you can do these things if you use a library like React on top of WCs. But that negates the argument that you don't need React-like libraries for this.

To sum up: we'd be happy to support WCs better in React. We don't want to rush it, and want to make sure this support is well thought-out. Additionally, we believe there are many things that raw imperative WC APIs don't give you — and for them something like React would be appropriate even in a WC world. Finally, there's this myth going around that once you write React code, you can't reuse it as web components. That's not true — and as you can see from the documentation it's a few lines of code: reactjs.org/docs/web-components.ht...

Hope that makes sense, and provides some additional context!

[1]: For example, if I'm not mistaken, the semantics chosen by Preact make introducing a new standard property to DOM base element potentially a breaking change for the web. We try to avoid such problems if possible — precisely because React did learn from MooTools and we don't want to do another mistake like what happened with Array.prototype.flatten().

Collapse
 
calebwilliams12 profile image
Caleb Williams

I just need custom event support in JSX. There's not a lot else that's too difficult to do when just considering web development. Using refs and componentDidMount is cumbersome, adding native event handling would make a huge difference in how easy it is to work with React and web components.

Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

Hey Dan, thanks for dropping by 👋

The problem is that there's no single "web component community".

Totes. It's pretty frustrating trying to compare the advocacy efforts in the wc community with what your team is blessed with. Then again, there's no "querySelector" community either. Open standards might not be sexy but they make the world go round

These libraries don't agree on a single standard

They agree on at least two: the HTML spec and the DOM spec. Those are the standards we're working with. I appreciate the React team's need to consider platforms beyond the web, and I'm grateful that's not my concern at the moment as a web developer, since that sounds like a hard problem. But server-side rendering is beyond the scope of the question "what should be the web's component model" in my humble opinion.

If you're using a library for defining and updating your web components declaratively, you're not following a conceptually different approach from using React.

As far as I've seen (and this is as a developer/user, not as a library author or community manager) the difference is about how to apply the concept of components. Should we use a bespoke all-js solution, or agree on standards for things like component model? Then, it's about how much code we're adding on to the web APIs. Justin Fagnani had an interesting hot take on this in the Polymer Community Slack

[A] meta-comment on the concept of "vanilla web components": [It's] a confusing term. Some people think "vanilla" means it has no dependencies. I think that's a silly constraint. I tend to think of vanilla as meaning that there aren't framework-style custom APIs intervening in writing or using a component. ie, LitElement is vanilla because it extends HTMLElement and you override the standard lifecycle methods like connectedCallback as necessary. StencilJS isn't vanilla because the component class doesn't extend HTMLElement and you don't implement standard lifecycle callbacks, you implement compnentDidMount and such.

Actually in the same thread, that same Justin sort of preempted your next point:

there's plenty of things that are very hard to do with an imperative abstraction like vanilla WC APIs

To loosely paraphrase - Now that we have the DOM API, we don't need jQuery, but we still sometimes need libraries like jQuery. The low-level WC APIs are best used by library authors. There might be some simple cases (like a <lazy-image> element) that are best implemented and shipped with bare-bones browser APIs, but in most or almost-all cases, it would be better to use a library.

we'd be happy to support WCs better in React.

Amazing

We don't want to rush it, and want to make sure this support is well thought-out.

Sure!

Additionally, we believe there are many things that raw imperative WC APIs don't give you — and for them something like React would be appropriate even in a WC world.

Totes. I'm not sure that's even a debate. For me, that "something like React" is the option which lets me hit save then reload without any intervening tools.

I Hope the interop promise of web components lands in the massive react community soon. In the mean time I'll be declaratively defining reactive templates in LitElements et. al., and running them without babel, webpack, or any other tooling (unless I decide to bring them in as nice-to-have optimizations)

Thanks again for stopping by, it's great that you decide to add your voice to this discussion. 😊

Collapse
 
dan_abramov profile image
Dan Abramov • Edited

It's pretty frustrating trying to compare the advocacy efforts in the wc community with what your team is blessed with.

Not quite sure what you meant by this, but I'd like to emphasize we don't currently have developer advocates working on React web. People you might talk to on Twitter are just JS engineers who happen to work on it and like open source.

But server-side rendering is beyond the scope of the question "what should be the web's component model" in my humble opinion.

Maybe. It's in the scope of "how to write a performant application" though, which is why a lot of people care about it. Since it's in the scope of what React does (and perhaps holistic thinking like this is part of the reason people don't hurry to ditch React), we need to consider any decisions there very carefully — especially because they impact the web component communities too.

The same goes for all other things we consider our concerns (such as dynamic loading of UI code). They might not be low-level enough to be in the spec, but we think it's much easier to write product code when the component abstraction is aware of them. Which is why we think it's worthwhile to keep working on React.

Overall it doesn't seem like we disagree on many things? I wish these discussions were less polarized in general, as they keep being about how we need to ditch one and use the other whereas the tools are more complementary in nature. My personal impression has been that web components solve organizational problems more often than technology problems (e.g. how to share UI between teams that don't want to agree on a library). But those absolutely are valid problems, and it's great if we can have solutions to both spectrums.

Cheers!

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

Overall it doesn't seem like we disagree on many things?

Yup

I wish these discussions were less polarized in general.

100%

we need to consider any decisions there very carefully — especially because they impact the web component communities too.

My spidey-sense is tingling. The React team isn't the w3c or the whatwg. Big questions that affect the future of the web should be the purview of standards bodies, not library authors. I'm not against awesome JS that makes things work in lieu of agreed-upon standards, (and let me take a moment to praise your team for their technical accomplishments) but we have a standard component model now - one that's not just theoretically standardized but also universally implemented (!RemindMe 6 months or so when Edge releases support).

It happens to be that I prefer not to use React because of VDOM and JSX, which for my use cases are in my (very) humble opinion overengineered. I like hitting save and reloading. I like inspecting a custom element and seeing its DOM properties in the JS console instead of some custom dev tools plugin. I like working without source maps (and if I had my druthers lit-html would be written in JS not TS 😉). I like standards and I like the web. I don't like it when people think that "web developer" has to mean "react developer"

My main issues are that React's success has made babel and webpack de rigueur requirements (I just spent an hour with a mentee unscrewing babel for a one-file 700 LOC react js script for a wordpress site. Madness!), and that a lot of the advocacy for react has come as mud slinging against standards (and I hope it's clear that I'm not pointing the finger at you personally))

Thread Thread
 
dan_abramov profile image
Dan Abramov

My spidey-sense is tingling. The React team isn't the w3c or the whatwg. Big questions that affect the future of the web should be the purview of standards bodies, not library authors. I'm not against awesome JS that makes things work in lieu of agreed-upon standards, (and let me take a moment to praise your team for their technical accomplishments) but we have a standard component model now - one that's not just theoretically standardized but also universally implemented

This is precisely my point. I think you're both asking that we do implement a tighter WC integration, and also that we don't make any decisions about how it should interop with React (and thus impact questions like server rendering). These are mutually exclusive requirements. And they're the reason we haven't historically been hurrying with this despite efforts like custom-elements-everywhere.com/.

React's success has made babel and webpack de rigueur requirements (I just spent an hour with a mentee unscrewing babel for a one-file 700 LOC react js script for a wordpress site. Madness!)

Re: Babel, fair, although you could use it as a JSX-only transform if you don't care about newer JS features. React doesn't force you to use ES6. I found it curious that people who complain a lot about JSX tend to also love SASS — which, if you think about it — is a transform just like JSX.

Re: webpack, this has nothing to do with React. People use it because they write more complex apps, and shipping them as a single bundle without code splitting (or as ES6 modules!) hurts the users. If you don't need bundling, you can use React as a script tag and not do any bundling: reactjs.org/docs/add-react-to-a-we...

a lot of the advocacy for react has come as mud slinging against standards

Let me know when you see it and I'd be happy to chime in! I've also seen a lot of unjustified stabs back at React which doesn't help either.

Thread Thread
 
thepassle profile image
Pascal Schilp • Edited

Can't believe im about to be 'that guy' on an internet forum saying this, but im running out of fingers to count the times I've shook my head after seeing a "use the platform LOL" jab from the React community.

Having said that, I really do appreciate the sentiment of your comments in this thread, and you taking the time to engage in (what feels like an actual fruitful) discussion!

Overall it doesn't seem like we disagree on many things?

I wish these discussions were less polarized in general.

So now that we've established this, perhaps we can all slow down with the mud throwing a bit?

Thread Thread
 
dan_abramov profile image
Dan Abramov • Edited

im running out of fingers to count the times I've shook my head after seeing a "use the platform LOL" jab from the React community.

Sure and I'd like to see this fade away. But I think we also both know exactly where this sentiment comes from: the feeling of alienation. Some developer advocates shame developers for large bundles — and in many ways, this is justified. But often there's a sense that they forget why we ended up here.

React users would love to not have to npm install a date picker and bloat their bundles! If they need to "use the platform" then why doesn't that platform ship the features they actually ask for? Instead of a <carousel> they get an <aside>. Features like service workers are touted as a solution to many problems in the web, but their ergonomics are so under-designed that people actually have to change domains to bust the cache from a broken build (I’m not making this up).

Now again, I understand the other side to all of this. Standards are hard etc. But I think the aggressive anti-library message (while promoting a library on top of WCs) coupled with not listening to people's problems has somewhat poisoned the "use the platform" movement. That's why many people perceive it as sarcastic now, unfortunate as it is.

I'd like to see that change though! On the React team, recently we have been tightly working with browser vendors. There is a sense that people are more receptive to hearing things we learned, and we're very optimistic about this progress.

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦
Thread Thread
 
dan_abramov profile image
Dan Abramov

Great stuff! I'm sure a lot of developers will appreciate this as a move in the right direction.

Collapse
 
bhaibel profile image
Betsy Haibel

I think you'll find there's plenty of things that are very hard to do with an imperative abstraction like vanilla WC APIs.

Would you mind expanding on what you mean by this? I'm on board with a lot of your comment. In general, while I prefer web-standards-based work to framework-based work, I have a hard time as seeing web components as "there yet." I agree with you that the fragmentation in the "web components" community harms it way more than React does, and that trying to frame web components as a replacement for React is likely to lead to using web components poorly. (For example, I see a lot of folks trying to use web components for page templating in a "React-like" way; I think this is a mistake.)

HOWEVER. "Imperative abstraction," in the context you're using it and without further explanation, seems like functional-purist FUD. One of my concerns with the emerging "functional React" default is the way it encourages folks to give their entire page over to a global state, rather than having components maintain their own boundaries. In my experience, separating out "API data state," component-level state, and route-based state really simplifies and clarifies SPAs. I suspect you have a different perspective here, which is fine. But I don't think that that different perspective justifies spreading FUD over "imperative" (object-oriented) code.

I'm not saying this as a gotcha. I think that integrating the actor style that (good) DOM-oriented approaches use with React's emerging functional consensus has always been a hard problem, and that the additional complexity of the WC APIs makes it even harder. I think that dismissing valid stylistic and philosophical differences as "weaknesses of imperative code" will make it very difficult to get a useful seam between WCs and React components which drive them! So when you use language that I read as reflecting functional-purist assumptions, I find that really disheartening.

Maybe I'm over-reading this. I hope I am! Regardless, it's not at all clear to me what the "things" that you think are "hard to do" with "imperative abstractions" are, and I think that you unpacking that could really help illuminate some of the overlapping concerns that add unnecessary tension to WC discussions.

Collapse
 
dan_abramov profile image
Dan Abramov • Edited

Big fan of your tweets :D Thanks for your measured comment.

"Imperative abstraction," in the context you're using it and without further explanation, seems like functional-purist FUD.

I'm not sure we're on the same page here. React has always been on the pragmatic side of FP — full of imperative escape hatches. We're definitely not purists. Some people in the community are, but they're a minority and don't reflect how React is being used by most folks in practice.

One of my concerns with the emerging "functional React" default is the way it encourages folks to give their entire page over to a global state, rather than having components maintain their own boundaries.

This sounds like a misconception about React to me. React doesn't have a concept of global state, and emphasizes component local state very strongly. That's all you'll find in our documentation, for example: reactjs.org/docs/state-and-lifecyc.... We strongly encourage to keep component state isolated, and to pull it down to the place where it's actually needed instead of hoisting it all on the top:

There should be a single “source of truth” for any data that changes in a React application. Usually, the state is first added to the component that needs it for rendering. Then, if other components also need it, you can lift it up to their closest common ancestor.

(This is a quote from the React docs.)

In my experience, separating out "API data state," component-level state, and route-based state really simplifies and clarifies SPAs. I suspect you have a different perspective here, which is fine. But I don't think that that different perspective justifies spreading FUD over "imperative" (object-oriented) code.

No, we're fully in agreement here. Again, I think you might be confusing React with something else. (Or perhaps, with some highly opinionated way of writing React.)

I don't consider local state "imperative" in that sense. I was only reflecting on the imperative nature of DOM API (node.property = value), as opposed to a declarative one (return { property: value }) — although even that is allowed in React for some use cases like focus or media playback.

I also realize the words "imperative" and "declarative" have subtle meanings, so to clarify, I'm only talking about the difference of mutating views vs describing what should be rendered.

We consider local state to be the most important feature of React. We are considering moving to a slightly more functional way to express it (conference talk if you're curious: youtube.com/watch?v=dpw9EHDh2bM) but it's still entirely local and has all the necessary imperative escape hatches. (Ironically most of the criticism of our proposal focuses on it being not "pure".)

It's not at all clear to me what the "things" that you think are "hard to do" with "imperative abstractions" are

In the beginning of this year, I gave a talk about the next things we're working on with React: reactjs.org/blog/2018/03/01/sneak-... (it's a different one from what I linked earlier in this comment). And here's another talk by my colleague Andrew: youtube.com/watch?v=ByBPyMBTzM0.

I think they capture those exact things so if you're curious, please take a look and let me know what you think. In short: I'm talking about non-blocking rendering ("time slicing") and declarative loading states ("suspense") without committing results to the DOM until they're ready. This is something you can't do if node.property = value is your only primitive. But you can do it if your abstraction lets you describe changes without immediately applying them. (Display locking DOM proposal is a step in the right direction.)

Hope this makes some sense. Really sorry you got the impression we're purists from my post. Not my intention at all! In fact purists usually scoff at React for being too "impure".

Collapse
 
tracker1 profile image
Michael J. Ryan

I can't speak for how anyone else uses React, but I'll use both functional and class syntax for different types of components as needed... I also break up my redux reducers against specific feature areas. I tend to favor redux/global state for many things, but will break out of this where it makes sense.

In the end, I find being able to reason about what a component is doing makes it easier to write and maintain them. I also absolutely separate areas of my applications by feature area. This may contain api/state/component combinations in whole or part.

I think my biggest issues regarding WebComponents, is they're difficult to write unit tests against. Beyond this, you cannot within the DOM pass state object and/or event handlers to child objects in a declarative way. This means you can't really write applications as easily (in my opinion). The way React works is much closer to how I conceptualize components than what WebComponents offers.

As an aside, JSX is absolutely something I enjoy that some disagree with. To me, it just makes sense, and it's so close to what I wanted when E4X was a good option with Mozilla browsers, Flash/Flex and VB.Net. Unfortunately lack of cross-browser support pretty much killed it. imho, JSX is actually better.

Collapse
 
leob profile image
leob • Edited

Great points ... my takeaway from this is that comparing React and WCs might be like comparing apples and oranges. Therefore it seems to me that the author is a little too hasty to predict that WCs will "replace" React any time soon, rather I expect both to coexist and complement each other well into the future.

React is giving us more than just a way to author components, it's also bringing architectural "best practices" to the table when we want to compose these components into complete apps. WCs typically offer a fairly 'low level' procedural/imperative API and the rest is up to the dev to figure out.

As soon as you put libraries on top of WC's to mitigate these shortcomings/limitations then you end up not much different than when you use React to build your app.

React is also arguably a "broader" solution than WCs (look at React Native, SSR etc).

So you could say that React (at least 'React Web') could be built "on top of" WCs, but not the other way around. React is more an approach or methodology to compose components and create apps, the "low level" components themselves could perfectly well be WCs.