DEV Community

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

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.