9 ms·
Anyone else feel like suspense was a major step in the wrong direction for React? I've noticed so many more cases of applications breaking in difficult-to-track
by 0xFACEFEED 5y ago
Anyone else feel like suspense was a major step in the wrong direction for React? I've noticed so many more cases of applications breaking in difficult-to-track-down ways because of how errors are propagated with suspense. Maybe I just don't "get it".
- sophiebits 5y agoDo you mean with React.lazy? Suspense hasn’t been used yet outside of that in released versions of React. Would be curious what specifically you ran into though; it shouldn’t make errors hard to debug.
- ferdowsi 5y agoYou'd be correct, it's a really unfortunate design decision. The author of CrankJS has a full critique here. https://crank.js.org/blog/introducing-crank https://crank.js.org/blog/introducing-crank
- nawgz 5y agoSuspense is a pretty weird step into "magic" for a library that has been a pretty damn thin layer on top of JS for so long, I fully agree with that. Using it is somewhat pleasant in terms of terseness, but very unpleasant for the fact I do not have a good understanding of how the lifecycles of the async resource(s) influence the render schedule, which is really the core of React from my perspective
- deckard1 5y ago> weird step into "magic" for a library that has been a pretty damn thin layer on top of JS I mean, hooks are totally this. They fundamentally break the concept of a "function" despite calling them "functional components." They use this weird notion of state (i.e. magic). The best way I can describe it is a cousin of dynamic scoping from the bad old LISP days. Back before lexical scoping was invented. So you end up with all these caveats and gotchas. Go look up useRef with useEffect and useCallback. It's all a total clusterfuck. The lifecycle methods weren't perfect. But at least you could understand them. But I lost a lot of respect for React way back when they started fussing with the lifecycle API, a year or two before hooks. Their vDOM abstraction was starting to leak heavily and they were struggling to make sense of it. When people say they like React, I really suspect they mean they like JSX. React, itself, is a mess. Always has been.
- ironmagma 5y agoThey’re called “function components,” not “functional”, because they reside within a JS `function` as opposed to a class. The word you’re looking for is side effect. The `use*` family of functions operate as hooks from the component into the renderer, so the renderer can easily see what dependencies a component has. This is accomplished by producing side effects. The lifecycle methods are all well and good but there was an ergonomic problem with them with shouldComponentUpdate. No one wants to implement that function by hand when it involves whitelisting all props you want to produce a rerender, which is most of them. People would always write bugs. It’s much easier to create a list of dependencies a la second argument to useEffect.
- dragonwriter 5y ago> It’s much easier to create a list of dependencies a la second argument to useEffect. Even easier to just not do that, either, as in Solid’s version of hooks.
- ironmagma 5y agoHonest question, is what you’re referring to this[1] or something else? I’d be interested to see how hooks could work without side effects. [1] https://github.com/ryansolid/component-register-hooks https://github.com/ryansolid/component-register-hooks
- dragonwriter 5y ago> Honest question, is what you’re referring to this[1] or something else? I’m talking about Solid, the web framework, which has hooks (they call them “effects”) similar to those in React, but which do not require explicit dependency lists when specifying them. https://www.solidjs.com/tutorial/introduction_effects https://www.solidjs.com/tutorial/introduction_effects
- ironmagma 5y ago
- recursive 5y agoPretty damn thin layer? The language with its own syntax and build tools? The one with JSX? React is one of the thicker layers I've seen.
- nawgz 5y agoOh no, JSX that compiles down to the exact set of `new Object` calls you would expect in a tree structure, how can I understand such complexity!? Really, you're kidding yourself if you think React isn't far simpler than Angular or Vue or any of these other frameworks. If you have some different direction in mind, fine, but I doubt it scales
- recursive 5y agoDon't misunderstand. I like JSX. However, that doesn't compel me to call it thin.
- nawgz 5y agoI find that strange. For example, I would call Angular or Vue "thick" with their extra templating files and DSLs and two-way binding. I would call React thin because the JSX components you build are transparently just objects, they interact with types super gracefully because components are just classes with a method that returns nested objects, and your code is just invoking JS and producing JS until the React library itself performs the side effect of rendering. I understand that React has abstractions and a heavy scheduling engine and all sorts of complexity, but a React component - the core concept of React - reuses directly JS concepts in place of introducing its own in most situations. That is thin. I admit that if you are just thinking of libraries in general, of course a frontend framework is not "thin", but for a library which enables true composability and reuse, React is so thin compared to is competitors. Which seems a reasonable de facto context for a conversation about React.
- recursive 5y agoI don't think it's thin even in that context. For example, invoking a hook comes with a bunch of rules beyond "just javascript". You shouldn't invoke a hook conditionally. You shouldn't invoke a hook in a loop. I've run into state/props mismatches due to the diff resolving differently than I thought it should. It's possible to solve this, but it further breaks the illusion of a thin layer. Maybe it's a different way of thinking, but I don't think two-way binding is inherently thicker. To me, thickness is related to the amount of "mechanism". A handlebars-type templating system seems much thinner to me.
- dexwiz 5y agoReact started as a nice rendering library. Then it was infected with all sorts of Functional Programming paradigms grafted on top of Javascript. At the same time people wanted React to be a framework for client side rendering, not the thin layer it was. Stateless components are a good idea, but their implementation as functions and hooks leaves any JS programmer not familiar with React scratching their head. Throwing Promises for Suspense is basically Algebraic Effects. Redux and a million other libraries tried to solve data management, none of them doing it in a classical K/V store. Now every app I touch I have to find its special version of reducers and selectors. I like front end programming and Javascript overall. Components are a nice abstraction, and life cycle hooks make sense in real life contexts. But React reeks of developers who think they are too smart for their day job and want to redefine UI programming just to render a button with an event handler.
- handrous 5y agoYeah, I started going "well, time to look at the rest of the ecosystem for the Next Thing" with Hooks. Given requirements that meant, to progress, they were going to need to either: 1) Tell devs that sometimes they would simply have to use classes/objects for some components, because certain performance enhancements or state-management would only be available there, or; 2) Partially re-implement objects with really bizarre declaration syntax, in a language that already has objects—shit, its functions are objects, and maybe it's changed but I read the hooks code when it was added and it was just some FIFO property/method queues, rather than tables, tied to a damn object representing your component in React's core state-machine; They chose #2. [EDIT] yes I'm aware that one reason they prominently gave for hooks was that inheritance hierarchies could cause problems in React codebases, but that seems woefully insufficient as a motivation for writing a crippled version of objects/classes that lack the features they had problems with, rather than just telling people "maybe stop hitting yourself?" and continuing to use what the language already provided, which everyone already understood.
- dexwiz 5y agoThe thing that blew my mind was React gave a decent abstraction for externally set values vs internally managed values in props/state. And then the community immediately declared State as evil, and boiled the ocean to replace it. All UIs need state. Yes state is bad in most cases and makes programming harder. No abstracting it into 4 different files doesn't make it any clearer. There was an issue with composition in React. HOC didn't scale very well, and Inheritance is almost always Bad (TM). That said, I do think hooks were an esoteric choice versus a more explicit service registration/DI pattern.
- dmitryminkovsky 5y agoI thought so too for a while, but after using concurrent mode a bunch I came to agree that the usecases it’s built to support (rendering fallback UIs while async processes occur) actually do belong as first class citizens in the framework. It’s the kind of this you implement yourself over and over again. And often the async processes you’re waiting for are React components themselves to load and parse. I’ve come to like the implementation too. I’m glad to see it mature and I like how they’ve taken their time with it.
- eyelidlessness 5y agoSuspense, itself, is somewhere in the range of “uninteresting” to “neutral”, in my opinion. Its direct use case would probably have been better solved by: 1. Providing a general signal to reuse the existing DOM node (or subtree, but that’s less useful) without performing any render logic. 2. Allowing components to use built-in suspension semantics (generators, async/await). The former would have other really useful applications, like partial/selective hydration. The latter is closer to both the language and the original spirit of React, which embraced being close to the language. (Who ever thought “throw a Promise” for meaningful control flow before this?) That said, it’s pretty clear from what React team has discussed since Suspense was introduced that it’s part of a larger strategy. Specifically: React Server Components. They’re laying the groundwork for that now, in stabilizing Suspense SSR. I’m more interested in a less sophisticated solution, but it’s pretty clear RSC is both where React is heading and requires a more opinionated foundation like Suspense. > difficult-to-track-down ways because of how errors are propagated with suspense I suspect this has more to do with concurrent rendering generally, than with Suspense itself. Debugging concurrency is harder in general. React's simplistic top-down rendering model was successful in part because it was simplistic and top-down. - - - All of that may not be justified for your needs! React is positioned for a very specific set of use cases (even if it’s over-used for similar-looking ones). You may find you’re more comfortable in a more simplistic VDOM (and that’s okay!) or a library based on reactivity (if so, and if you’re coming from familiarity with React, I’d suggest giving SolidJS[1] a look; its rendering model is much closer to the DOM). I’ll also mention that I’ve spent more time with Preact than React, and have found its Suspense implementation much easier to work with and debug. 1: https://www.solidjs.com/ https://www.solidjs.com/