[HN Gopher] What's New in React 18?
___________________________________________________________________
What's New in React 18?
Author : nathias
Score : 133 points
Date : 2021-09-29 17:14 UTC (5 hours ago)
(HTM) web link (yagmurcetintas.com)
(TXT) w3m dump (yagmurcetintas.com)
| literallyaduck wrote:
| Any discussion of NextJS and how it would work with the new SSR
| technologies?
| Waterluvian wrote:
| I'm pretty delighted by a lot of the concurrency stuff that's
| popping up.
|
| At this very moment I'm wrestling with a UI where the left side
| is a list of cartographic datasets, and the right side is a rich
| OpenLayers preview renderer.
|
| I want the right side to be "low priority" where it tries to
| render a preview, but is happy to abort or not get done in-time
| if the user selects a different dataset. At the moment, the
| processing acquiring and rendering the preview makes the rest of
| the UI a bit laggy.
|
| I suspect a good bit of my custom code can be replaced with some
| of this transition stuff.
| stevemk14ebr wrote:
| You issue is likely due to a heavy computation blocking the
| main js thread (rendering). In this scenario the suspense api
| will not solve the UI lag. I've had the exact same pattern with
| a home build markdown editor where the right side preview
| should render quick, but lag behind if too heavy and give
| priority to left hand side. I tried the alpha and speak from my
| own experiences, you'll have better luck by offloading render
| computations to a background web worker. The preview can do a 1
| time synchronous render, cache the result in it's local
| component react state, then all future state updates are
| computed async on the background thread. Main thread left
| unblocked
| Waterluvian wrote:
| It's considerably more complex than that. There's just a lot
| of stuff that gets compiled and rendered. No single part
| takes more than a few milliseconds, so I can bin it across
| many tasks.
|
| Picture a canvas that I'm calculating then drawing tens of
| thousands of elements to before displaying it. Very binnable.
| Very hard to get right to a point that you can't "feel" the
| lag when working with the rest of the app.
|
| I also explored web workers but it's currently more hassle
| than I want to be bothered with.
| pier25 wrote:
| If your use case requires rendering and updating thousands
| of components, maybe React wasn't a good fit?
|
| You could try switching to Preact which has better
| performance and should be painless.
|
| https://krausest.github.io/js-framework-
| benchmark/current.ht...
| Waterluvian wrote:
| Not components. Elements that compile to a canvas. Think
| tens of thousands of points, lines, polygons, all drawn
| as vector or raster images. Ie. compiling a deeply rich
| interactive map of data.
|
| I appreciate the advice but I didn't provide sufficient
| information for informed responses. It was just a general
| comment about why I'm excited for React 18 to help better
| manage concurrency in a number of ways.
|
| Suspense will also be nice because I can eliminate a lot
| of my own "loading screen" logic.
| pier25 wrote:
| > Not components. Elements that compile to a canvas.
|
| Ah right. I thought the canvas example was just an
| example.
|
| Still, a faster framework would be better for high
| performance use case, no?
| brundolf wrote:
| The problem comes when the rendering itself is the
| bottleneck. You can't put that on a Worker because it's so
| entwined with the DOM. We ran into this several times at a
| past company where our UIs rendered elements in the 10s of
| thousands, and we had no real recourse except to optimize
| everything to death (and things were still laggy). In one
| case we implemented our own, bespoke, crappy equivalent of
| suspended rendering and it was a mess but it was just barely
| worth it because we were so desperate.
| KronisLV wrote:
| > We ran into this several times at a past company where
| our UIs rendered elements in the 10s of thousands
|
| Maybe that's the real problem? If at all possible, such
| intensive tasks should be done in native frameworks, not
| web technologies. Alternatively, why not simply do less?
| Pagination, extracting separate sections of the app into
| separate pages/views and many others are perfectly valid
| approaches to something like that in my eyes, not just
| turning to low level optimizations.
| brundolf wrote:
| We had various project constraints and user demands that
| made most of those suggestions untenable. We used
| pagination in some places, but in others our users
| refused to accept it (they wanted Ctrl+F, fast browsing
| of huge datasets, etc). Writing a native app would have
| been miles outside the realm of possibility (we had a
| small team making a very complex product, none of us had
| native app experience, we needed to support multiple
| platforms, we specifically needed instances of our server
| to be able to serve up their own GUI, we needed to be
| able to interface with them from arbitrary remote
| machines without installing new software, etc).
|
| To use the words of a commenter in another thread: I
| didn't provide sufficient information for informed
| responses. It was just a general comment about why I'm
| excited for React 18 to help better manage concurrency in
| a number of ways.
| peanut_worm wrote:
| I haven't used React in a while, what does it offer that
| WebComponents do not?
| econnors wrote:
| a coherent strategy for keeping state and having the UI respond
| to changes in state
| flowerlad wrote:
| That works well... until you have stateful components and you
| want to send in new props. At that point the recommended
| approach is to replace the entire component by using the key
| property.
|
| For simple components, especially stateless ones, React works
| well. When the component needs to manage user interactions it
| needs state, and then if you need to update props you have to
| make a new instance of the component, and that point React
| has failed in its promise.
| lucasmullens wrote:
| > At that point the recommended approach is to replace the
| entire component by using the key property.
|
| Where did you hear that? React.Component has both props and
| state and both seem to work pretty well together, and you
| definitely don't need to destroy the component by changing
| the key property just because props changed.
| flowerlad wrote:
| > _Where did you hear that?_
|
| https://reactjs.org/blog/2018/06/07/you-probably-dont-
| need-d...
| paavohtl wrote:
| What do you expect to happen? You ultimately have to store
| the state somewhere. Either it lives in the component, or
| outside of it, or you figure out some strategy to combine
| the two.
| flowerlad wrote:
| Once you realize React doesn't work for complex
| components it loses its attraction. Web Components are
| conceptually way simpler and work well. See example:
|
| https://github.com/wisercoder/uibuilder/blob/master/WebCo
| mpo...
| crooked-v wrote:
| Simpler? I don't see it. That looks way more verbose than
| a React equivalent component I would write.
| paavohtl wrote:
| I don't really see anything here that would be massively
| more complex in React. And besides, I've been hurt enough
| times by manual DOM manipulation to never want to do it
| again for interactive UI. It's a maintainability
| nightmare.
| econnors wrote:
| I'm not sure what you mean, could you clarify? Having a
| stateful component render something different based on a
| prop change is core to react. Using the key property
| "resets" the component by rendering a new one, but just
| because you use state doesn't mean you can't change props.
| flowerlad wrote:
| It is recommended by FB:
|
| https://reactjs.org/blog/2018/06/07/you-probably-dont-
| need-d...
| dragonwriter wrote:
| > When the component needs to manage user interactions it
| needs state, and then if you need to update props you have
| to make a new instance of the component
|
| That would suck and make React completely unusable, but it
| isn't true at all. Assuming that there are necessary
| state/prop interactions to track (sometimes the two arr
| largely orthogonal, so you don't need this) you might need
| to add additional state variables to do last value tracking
| for props, and then do (with useEffect hooks in a function
| component, for instance) state updates based on prop
| changes as needed, but you don't need a new instance on
| prop changes, generally.
| flowerlad wrote:
| Please read React documentation:
|
| https://reactjs.org/blog/2018/06/07/you-probably-dont-
| need-d...
| dragonwriter wrote:
| You made a "you have to do X" claim, and then point to a
| documentation page that shows you don't have to, even
| though it is the recommended pattern.
|
| React works fine with components that don't follow the
| recommendation, though if you freely mix internal state
| updates and external updates via props that shouldn't
| represent instance changes, you can very easily make
| something unnecessarily difficult to reason about. So the
| _recommended pattern_ of either doing a fully-controlled
| or fully-uncontrolled component is a sensible
| recommendation that makes sense to guide design. But
| nothing will break and the React cops won 't arrest you
| if you use props driving state, though if you do too much
| of that whoever had to maintain your code may be upset.
| flowerlad wrote:
| I am assuming you're debating in good faith (and not just
| trying to win an argument). The recommendation made in
| the docs is very well justified. All other techniques are
| a mess, and lead to maintenance problems and bugs. Just
| replace the component by changing the key... you can
| thank me later.
| throw_m239339 wrote:
| what does web component offers at first place is the real
| question. It's a spec but beyond that, Web Component doesn't
| really solve any of my architectural problems as a front-end
| developer. Instead of web components for instance, I would have
| preferred a DOM diff API as a standard which would have been
| far more useful that web components, all things considered.
| dmitriid wrote:
| Someone already pointed to Rich Harris' article on dev.to, but
| there are other things:
|
| - form participation without javascript hacks (they are called
| "an API", but it's a hack) https://web.dev/more-capable-form-
| controls/
|
| - SSR
|
| - splitting SVGs into components
| https://twitter.com/Rich_Harris/status/1354165883648827401?s...
|
| - not breaking accessibility by default
| https://twitter.com/sarahmei/status/1198069119897047041?s=20
|
| and a million other things, big and small
| 5e92cb50239222b wrote:
| Rich component libraries like antd and material.
|
| https://ant.design/components/overview/
|
| https://material-ui.com
| purple_ferret wrote:
| employment opportunities
| paavohtl wrote:
| What does WebComponents offer that also React offers, other
| than some form of components?
| ajkjk wrote:
| React does a lot more than WebComponents. Primarily the
| reactive programming model of only updating subtrees whose
| props change, but also an entire parallel tree of state/context
| updates for propagating data that lives alongside the component
| hierarchy.
| reidjs wrote:
| In my experience React, despite its complexity, was always far
| simpler to use than WebComponents because it has clearer
| documentation and established patterns. I'm sure WebComponents
| can do everything React can do, but they do not have anywhere
| near the ecosystem and developer support you get with React.
| [deleted]
| CapitaineToinon wrote:
| There is this article (https://dev.to/richharris/why-i-don-t-
| use-web-components-2ci...) by Rich Harris, creator of Svelte
| which explains pretty well why he personally doesn't use web
| components.
| ravenstine wrote:
| I feel like everyone has the wrong idea about web components.
| Perhaps it's in the name. There's no "WebComponent" class on
| the window object, but there _is_ an HTMLElement you can
| extend and a `window.customElement` registry for tagName
| invocation, a thing called a shadow root, and so forth. Those
| are all things that I am glad exist. If I thought of them
| grouped together as "Web Components" and compared that to
| components in frontend JavaScript frameworks then yeah, I
| guess I'd be disappointed. Otherwise, the people who say they
| "don't use" web components are being as unreasonable as it
| would be to say to not use the `<video>` element because it
| doesn't support all the things that `<canvas>` does with some
| 3rd party library for compositing.
|
| Custom elements are awesome for small things that don't need
| to appear in an SSR context (assuming you're using shadow
| DOMs). No, they don't support composable stylesheets,
| whatever those even are, but seriously, who really needs
| them? If what you are doing is complicated enough that the
| browser's native APIs are too obtuse then yeah go for
| something like React or Svelte. No matter what, there's going
| to be _something_ that someone 's JavaScript library is going
| to do better than the browser. I'd use uncommon browser and
| language features if they made sense for a task.
|
| The `<template>` and `<slot>` elements are really dopey and
| hard to understand. That's where something like React or
| Svelte comes in. Nobody would use either of those libraries
| if they didn't have better _templating_ than the browser.
| javitury wrote:
| Webcomponents are a huge mess, caused partially because it
| requires to do (some) composition in html. React is much
| simpler, it uses basic html elements (div, input, ...) and
| event apis to compose an application in javascript.
|
| These are some disadvantages of webcomponents that I can think
| of.
|
| - Can't register multiple versions of a webcomponent. Let's say
| you are using "x-dropdown"@2.0.0 which depends on "
| x-icon"@2.0.0 and "x-menu"@3.0.0 which depends on "
| x-icon"@1.0.0. Your app will crash because html tags can't have
| multiple versions ("x-icon" 2.0.0 and 1.0.0). It makes handling
| big projects a nightmare. And there are name collisions too.
|
| - Not all properties can be serialized into attributes as
| strings, so you end up just binding properties. Boolean
| attributes have special are weird when used in the javascript
| side (an empty string is treated as a boolean)
|
| - The shadow dom can be too restrictive and inflexible.
| Implementing portals for instance, requires using ugly hacks
| that depend on your webcomponent framework.
|
| - Some complex webcomponents are not interoperable among
| different frameworks.
|
| - Static analysis on webcomponents is poor and fragile. Compare
| declaring types of events in webcomponents, to declaring types
| of event handlers in react.
| krono wrote:
| It doesn't drive you mad with a needlessly complex syntax/API
| for one.
|
| Also no browser vendors that flat out refuse to implement parts
| of the spec (Apple [0]), or block proposals unless implemented
| in a highly specific way (all, here's one example [1], ugh
| politics).
|
| [0] https://bugs.webkit.org/show_bug.cgi?id=182671
|
| [1]
| https://github.com/WICG/webcomponents/issues/587#issuecommen...
| dmitriid wrote:
| is= is dead, and Safari had good reasons for it. On mobile,
| so can't quickly find the rationale.
|
| But it's the same rationale IIRC why built-in components are
| not extensible (even if this was one of the original
| promises): the browser has no way of knowing about the actual
| behavior of the object, which leads to all kinds of mess
| inside the engine.
| krono wrote:
| So many other parts had to be done in a specific manner or
| left out entirely to get committee consensus, yet this was
| written into the spec even though Apple has opposed it from
| the beginning.
|
| The validity of Apple's reasoning makes it even stranger.
| dmitriid wrote:
| Yeah, the whole thing about Web Components is weird. And
| is getting increasingly weirder.
|
| Quite recently Constructible Stylesheets were released in
| Chrome:
|
| - because lit wanted them
|
| - despite Firefox and Safari being against the state of
| the spec
|
| - despite Safari clearly stating they are not going to
| implement the spec, ever (there was a trivially
| reproducible race condition _in the spec_ )
|
| The entire discussion here:
| https://github.com/WICG/construct-
| stylesheets/issues/45#issu...
| awinter-py wrote:
| does web components have a usable templating language? last
| time I checked there was some kind of mysterious slot update
| thing that made interface code 2-3x bigger
| azangru wrote:
| > usable templating language
|
| ES6 multiline strings? Enhanced for convenience with a
| library like lit-html?
| vjust wrote:
| I like the way they describe SSRs , then talk about hydration -
| which of course has to lead into interesting videos on compressed
| towels , and peat pellets!
| [deleted]
| 0xFACEFEED wrote:
| 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".
| ferdowsi wrote:
| You'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
| sophiebits wrote:
| Do 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.
| dexwiz wrote:
| React 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 wrote:
| Yeah, 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 wrote:
| The 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.
| mixedCase wrote:
| > Then it was infected with all sorts of Functional
| Programming paradigms grafted on top of Javascript
|
| The whole thing has been functional programming from the
| start, if you know what algebraic effects are then the
| functional underpinning should be obvious to you as well as
| anyone with the slightest brush with FP. Hell, the original
| React prototype was in Standard ML, later ported to OCaml and
| _then_ JavaScript.
|
| > Throwing Promises for Suspense is basically Algebraic
| Effects
|
| The fact that you disregard Suspense as a head-scratching
| algebraic effect, instead of using simple "Promises" goes to
| show how much the JavaScript ecosystem seems to be about
| fooling people into doing functional programming without
| triggering their gut reaction of "FP is spooky unproven
| thing, but Node enterprise ready!".
|
| Imagine for a second that a Promise's .then is called .bind,
| put it in a thunk if you want to be extra precise and tell me
| what it is. Hint: It starts with "M" and it's just a monoid
| in the category of endofunctors.
| tshaddox wrote:
| Yeah, but if you are opposed to functional programming (or
| opposed to exposure to any new programming paradigms) of
| course you'll hate the library that has had perhaps the
| largest impact in bringing concepts from functional
| programming into the mainstream. That's perfectly
| understandable. But I like functional programming and I
| very much like React's impact in this area.
| dexwiz wrote:
| Using Functional Paradigms in a FP language. Cool! All
| for that.
|
| Bootstrapping pseudo FP styles into a Prototype Language
| with no types (JS is technically not OO, even `class` is
| just prototype sugar). Please no.
|
| I really like concepts behind FP. I have tinkered with
| Haskell and gone through Bartosz Milewski's Category
| Theory material. That said, its radically different than
| traditional Procedural or OO coding. It really needs
| language level support to be useful, and that usually
| starts with types and the compiler. Open up "FP"
| libraries in non FP languages, and you often discover its
| just the same objects as the rest of the language.
|
| That said, immutability is awesome. The concept of
| creating mutability boundaries and only exposing
| immutable data to external services and clients solves a
| whole class of bugs related to "who changed that?"
| flowerlad wrote:
| > _The whole thing has been functional programming from the
| start, if you know what algebraic effects are then the
| functional underpinning should be obvious to you as well as
| anyone with the slightest brush with FP._
|
| That's a lot of hot air. There is _nothing_ functional
| about React. Algebraic effects represent impure behavior in
| a functional programming language, such as input and
| output, exceptions, nondeterminism etc. all treated in a
| generic way. Impure behavior, including algebraic effects,
| is best avoided in functional programming.
|
| Sorry to post the link again, but _please_ read this:
| https://mckoder.medium.com/why-react-is-not-
| functional-b1ed1...
| bryik wrote:
| > There is _nothing_ functional about React.
|
| There is literally an example React component in that
| article that the author calls "pure and referentially
| transparent". How can this be if there is "nothing
| functional about React"?
| flowerlad wrote:
| But how many React components are that simple? Almost
| none.
| dtech wrote:
| > Functional programs are constructed using only pure
| functions
|
| If that's your definition, functional programs basically
| don't exist in the real world. Wikipedia (and I) don't
| agree with that [1], it specifically separates out pure
| FP [2].
|
| [1] https://en.wikipedia.org/wiki/Functional_programming
| [2] https://en.wikipedia.org/wiki/Purely_functional_progr
| amming
| flowerlad wrote:
| You didn't read the article. How to deal with impurity is
| described in the article.
| Grimm1 wrote:
| So what would you call this style of programming? Saying
| there is nothing functional about it seems like
| hyperbole. It's just not as pure as you'd like. I say as
| someone in the world of people who need to get things
| done, why do we/I care?
|
| I read the article FWIW, it didn't particularly convince
| me. I think even writing things in the style of
| functional programming, if that's what we want to call
| it, still makes it easier to reason about the code.
| Confining side effects to hooks also means there's only
| one place we have to reason about having non pure
| consequences.
| flowerlad wrote:
| Functional Programming is about purity. At the core of FP
| is pure functions. If you don't care about purity don't
| use FP. There is a lot to like about React, and Hooks and
| so on. Just don't call it FP though.
| Zababa wrote:
| No, it's not. The "purity" part was mostly pushed by
| Haskell enthusiasts, because Haskell cares a lot about
| purity. On the other hand, ML and its descendants don't
| care that much. Here's an example in OCaml:
| let add (x: int) (y: int) : int =
| print_string (Format.sprintf "x: %d, y: %d" x y);
| x + y
|
| This is a function. It's not pure. There is nothing
| that's stopping me from using it exactly the same way as
| a pure add implementation. OCaml is still a functional
| programming language. As said on Wikipedia: "Functional
| programming is sometimes treated as synonymous with
| purely functional programming, a subset of functional
| programming which treats all functions as deterministic
| mathematical functions, or pure functions.". Functional
| programming is not only purely functional programming.
| flowerlad wrote:
| Disagree. Functional programmers often speak of
| implementing programs with a pure core and a thin layer
| on the outside that handles effects. (Read the article I
| pointed to earlier.)
|
| If you don't have a pure core then you are not using FP.
| Zababa wrote:
| > There is nothing functional about React.
|
| The whole concept of React is to model the UI as a
| function of the state. React was first made in Standard
| ML (you don't really get more functional than this).
| Jordan Walke, the creator, went on to work on ReasonML,
| an hybrid between the OCaml and JavaScript ecosystems, to
| try to leverage the functional parts of OCaml.
|
| > Impure behavior, including algebraic effects, is best
| avoided in functional programming.
|
| This is wrong though. Functional programming doesn't shy
| away from impurity. Algebraic effects are a way to handle
| impurity, which is unavoidable.
| flowerlad wrote:
| > _Functional programming doesn 't shy away from
| impurity._
|
| Disagree. Functional programmers often speak of
| implementing programs with a pure core and a thin layer
| on the outside that handles effects. If you don't have a
| _pure core_ then you are not using FP.
| lhorie wrote:
| Sorry, but you're missing the forest for the trees. This
| is what wikipedia has to say: "Functional programming is
| sometimes treated as synonymous with purely functional
| programming, a subset of functional programming"[0]
|
| In FP as an umbrella, purity is not a hard requirement
| for the entire paradigm, only a predominantly pipeline
| oriented style based around expressions is (in contrast
| to, say, C, where one generally passes a pointer to the
| same state around to procedures that pick and choose what
| to modify in that state bag, as a series of statements).
| Common Lisp and OCaml are often cited as examples of
| functional languages that don't attempt to enforce purity
| guarantees even in terms of idiomatic usage, let alone at
| a compiler-enforced level.
|
| Using higher order functions for, say, promises
| (remember, they're stateful!) doesn't mean you're not
| using functional programming, just like using
| Array.prototype.map doesn't mean you're not using OOP (it
| implements fluent interfaces, if you haven't noticed).
| It's the _absence_ of functional tools /techniques that
| qualifies a program as not functional.
|
| IMHO, the unfortunate situation is that most JS people
| don't understand there are different degrees of
| functional-ness and certain guarantees only exist within
| specific subsets (and React doesn't conform to that
| subset).
|
| [0] https://en.wikipedia.org/wiki/Functional_programming.
| flowerlad wrote:
| Functional Programming has to serve a purpose. What is
| the point of functional programming?
|
| There are 3 benefits, mainly: (1) Ease of verification,
| (2) Parallelism and (3) Data-centric computation. (See
| article I linked for details.)
|
| Of these, Parallelism doesn't work in JavaScript. Since
| JavaScript doesn't support lazy evaluation, data-centric
| computation doesn't work that well either. That leaves us
| with the first benefit alone. But ease of verification is
| reliant on pure functions. If functions aren't pure then
| it is just regular code that isn't necessarily easy or
| hard to verify.
|
| React uses FP for a 4th benefit you won't find in any
| textbooks on FP: Marketing.
| phendrenad2 wrote:
| 1) New fast, easy framework bursts into the scene.
|
| 2) "Hey it doesn't work with edge case X, let's graft on more
| features to cover it"
|
| 3) Repeat step #2 a few dozen times
|
| 4) The framework is now neither fast nor easy, invent a new
| one and go to step #1
| nsonha wrote:
| There is nothing wrong with functional programming. It's a
| bit sad that redux and hooks give it a bad rap. Those things
| are NOT functional programming.
| lhorie wrote:
| > Throwing Promises for Suspense is basically Algebraic
| Effects
|
| I wish Dan Abramov hadn't made this analogy[0], they're
| nothing like algebraic effects. The core idea behind
| algebraic effects is more similar to something like
| dependency injection if it was generally possible to
| "deasync"[1] things in JS, except it leverages dynamic
| scoping instead of lexical scoping. The Suspense thing is
| closer to those jokes where the punchline is something along
| the lines of the programmer saying "have you tried to restart
| it?"
|
| [0] https://overreacted.io/algebraic-effects-for-the-rest-of-
| us/
|
| [1] https://www.npmjs.com/package/deasync
| azangru wrote:
| > I wish Dan Abramov hadn't made this analogy[0],
|
| I bet it wasn't Dan who came up with this analogy. My bet
| is on Sebastian:
| https://twitter.com/sebmarkbage/status/941214259505119232
| Zababa wrote:
| Further evidence of this in this blog post by Dan Abramov
| https://overreacted.io/algebraic-effects-for-the-rest-of-
| us/
| oaxacaoaxaca wrote:
| Very well said. I've been using React since it came out, and
| have been pushing back on Hooks since they came out.
|
| Class components are dead simple. A class, a setState method,
| this.props, this.state, and some lifecycle methods. SO easy
| for anyone to understand.
|
| Function components with hooks are not. A whole new (and
| unnecessary) paradigm; some mysterious hooks engine that
| needed new ESLint rules to be created just so people can keep
| the weird, delicate balance in place; hooks having their own
| timing problems, requiring usage of useRef which the React
| team tries to get people to avoid; etc.
|
| Frontend codebases used to have several layers, with React
| just being one of the thin ones. Now, nearly the entire
| frontend codebase is inside React world. I'm not a fan of
| this direction.
| flowerlad wrote:
| > _Then it was infected with all sorts of Functional
| Programming paradigms grafted on top of Javascript._
|
| Except it is not really functional. See:
|
| https://mckoder.medium.com/why-react-is-not-
| functional-b1ed1...
| snuser wrote:
| I think it's alright, the real problem that I've noticed is
| that a lot of developers tend to misconstrue what they need
| and bloat their projects in amazingly unmanageable way
| because it 'the way to do things according to random source
| x' which could be some weird abuse of state management
| systems like or redux or general application design
|
| FWIW I've seen it in many projects outside of the react/js
| world as well
|
| IMO there's been a general drought in books/material on
| reasoning/thinking about software in general in-favor of the
| framework/library centric mania we have now which focus on
| the least interesting aspects of the field -- the cynic in me
| thinks this is due to how we hire people but there's likely
| more to it than that
| dmitryminkovsky wrote:
| I 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.
| nawgz wrote:
| Suspense 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
| recursive wrote:
| Pretty 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 wrote:
| Oh 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
| handrous wrote:
| I think it could be argued to have been, at times,
| _conceptually_ thin, if you like.
|
| I agree that the tooling and even React itself, under the
| hood, have never been thin, or if they ever were it was
| only _very_ early on in the project. Well-functioning
| enough that one could forget about them at times, maybe,
| but not thin.
| deckard1 wrote:
| > 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.
| nawgz wrote:
| > 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
|
| State and React have always been fundamentally intertwined,
| so I'm going to heavily disagree with the claim that hooks
| are a new magic wrt React. Personally, as someone who has
| used React for a long time, hooks have been a very
| intuitive and terse new syntax to use the lifecycle hooks &
| provides a far superior way to deal with state machine
| transitions.
|
| > Go look up useRef with useEffect and useCallback
|
| I must say, as a pro web developer who has built loads of
| applications, including model editors, charts with React
| views on top of D3 math, interactive 3D renderings, graphs,
| you name it, I don't know why I would have anything to do
| with "useRef with useEffect and useCallback". I've never
| encountered any issue with these things. What use case are
| you trying to solve that requires those hooks and what
| issue with those hooks exists that is blocking you?
|
| > I really suspect they mean they like JSX. React, itself,
| is a mess. Always has been
|
| Oh, you just hated React all along, so you probably never
| understood it. Easy to see why you don't like it then.
| deckard1 wrote:
| > why I would have anything to do with "useRef with
| useEffect and useCallback". I've never encountered any
| issue with these things.
|
| The fact that you are asking and haven't hit the issue
| suggests you haven't actually used useRef before.
|
| > Oh, you just hated React all along, so you probably
| never understood it.
|
| Sure, asshole. I've only been using React for 6 years
| now. But whatever.
| nawgz wrote:
| > The fact that you are asking and haven't hit the issue
| suggests you haven't actually used useRef before.
|
| Or that you are doing questionable things with it? My
| guess from your tone and general confusion around React
| is that you expect useRef to have lifecycle hooks when
| the `current` value changing does not have any lifecycle
| hooks at all, and somehow your problem with that has made
| you rail against these hooks. Feel free to enlighten me -
| I have useRef and useEffect all over my codebases, I have
| never used useCallback though
|
| > Sure, asshole. I've only been using React for 6 years
| now
|
| Your own words: "React, itself, is a mess. Always has
| been". That's a comical statement to make if you're not
| emotionally biased against a library. Especially when
| that library is well-organized, with strong lifecycle
| guarantees, and gives you the strongest out-of-the-box
| composability of any comparable web framework.
|
| But no, it's you that's right, React sucks and doesn't
| work, it's the top JS library because JS developers are
| idiots right?
| steve_adams_86 wrote:
| I think this is a case of to each their own.
|
| I find hooks provide a far more declarative, testable,
| predictable developer experience. The simplicity of
| useEffect, useCallback, useRef, etc. makes it so I know
| exactly what I need to reach for when I need to accomplish
| certain things.
|
| It can get complex, but I find that usually means you need
| to back off and rethink things.
| ironmagma wrote:
| They'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 wrote:
| > 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 wrote:
| Honest 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
| dragonwriter wrote:
| > 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
| ironmagma wrote:
| Thanks. I don't understand how it's better though,
| wouldn't you need to start following the Rules of Hooks
| for this data retrieval (`count()`) as well, lest the
| renderer not know what all your dependencies are?
| deckard1 wrote:
| > They're called "function components," not "functional"
|
| They've been calling them functional components forever.
| https://github.com/facebook/react/blob/main/packages/reac
| t/i... I'm not sure why you're being a language nazi
| here. It's beside the points I was making anyway.
|
| > The word you're looking for is side effect.
|
| Enough with your patronizing. Obviously it is using side-
| effects. That's the entire point I was making. Functions
| (as in the term from "functional programming") _do not
| produce side-effects_. Functions _do not contain state_.
| You know what is good at containing state? Objects. The
| whole paradigm of an "object" is exactly what React is
| trying to do with functions. It's nonsense. You can't
| call a hook function outside of React's apparatus. When
| React calls one of these hook functions, it has to
| dynamically switch out the context. Which is where my
| analogy to dynamic scoping comes from.
|
| > an ergonomic problem with them with
| shouldComponentUpdate. No one wants to implement that
| function
|
| Yes, well, as I said React has always been a mess and
| there are just as many problems with useEffect. Throwing
| out the entire API is just dumb. Libraries are no longer
| universal. You have to consider whether it's using hooks
| or not. Especially since they never formally deprecated
| lifecycle methods. They just shrugged their shoulders and
| went "here's hooks, use them if you like them."
| ironmagma wrote:
| `StatelessFunctionalComponent` is not something that's
| publicly exported, at least from `"react"`. The
| convention is to use the `React.FunctionComponent`, or
| `React.FC` annotation.
|
| > Functions (as in the term from "functional
| programming") do not produce side-effects.
|
| This isn't true, even in the so-called "functional
| languages." Calling a function in Clojure could produce
| side effects, and the same is true in Haskell. In
| Haskell, calling a function that produces a side effect
| would necessarily return an IO monad, but that's a
| separate concern from whether the function invocation
| caused the side effect.
|
| > Libraries are no longer universal. You have to consider
| whether it's using hooks or not.
|
| You almost never have to think about this. Either a
| library provides hooks or it provides components. If it
| provides components, they could be implemented using the
| old component-style API or using function components; I
| have no idea, and it's irrelevant unless I plan to fork
| the library. Conversely if the library provides only a
| hook, I can easily wrap it in a thin component layer if
| that's the interface I prefer. The libraries are
| therefore effectively universal, since there's nothing
| that says I can't use a hook-based component within a
| function component, or vice-versa.
| kabes wrote:
| Not sure where I stand on this. On one hand function components
| and hooks give a nice way to extract logic into small reusable
| bits, way more than with class components.
|
| But on the other hand it becomes clear that decent performance
| with this approach requires all kinds of tricks and each react
| version adds more and more of these tricks with a steep learning
| curve. Shame since react started out with a very small, easy to
| understand API and that is what made it so popular.
| KronisLV wrote:
| You know, i'm not even sure that hooks were worth all of the
| problems with maintainability and readability that they've
| caused.
|
| I don't have the slightest doubts about me being in the
| minority here, but i've seen a large amount of projects which
| attempt to use multiple state hooks per component, and as a
| consequence the dependency arrays become brittle as the code is
| changed and sooner or later you're stuck with your page being
| in an endless rendering loop, because your logic isn't clever
| enough to actually untangle all of the state to decide when it
| needs to change anything: useEffect(() => {
| ... // a whole bunch of code }, [foo, bar]);
| useEffect(() => { ... // a whole bunch of code },
| [bar, baz]); useEffect(() => { ... // a
| whole bunch of code }, [foo, bar, baz]);
|
| Sure, you can be responsible with that stuff when you're the
| one writing the code, but when you open up someone else's
| project and have "the business" breathing down on your neck but
| have to untangle their uncommented code, you feel like some of
| the features are footguns in disguise. At least with
| shouldComponentUpdate all of the code that decides whether
| something should be done was in one place.
|
| You could easily comment that code out or change it. But with
| hooks, you need to untangle how all of the related calls to
| setState work and where every method for every state hook is
| called and why. I'm not sure that it was a good idea to
| decouple those.
| the_other wrote:
| I'm with you.
|
| They're confusing. The magic is too high. They maintain state
| in an invisible way. The abstractions are hard to follow,
| especially when you roll your own.
|
| The key issue for me is that they hide the rendering
| lifecycle from you. Everything's implied. One of the
| complaints with classes was that you had to learn the arcane
| weirdness of the lifecycle. But a) it's not that weird and b)
| it's much easier to learn when the callbacks are named after
| the stage in the lifecycle. The hooks way makes all that
| invisible.
|
| That said, I'm quite fond of the '[value, setter]' return
| type from useState. It's nice to use and nice to write. Just
| don't ask me to explain how it works for multiple re renders.
| 9wzYQbTYsAIc wrote:
| You can still use class components where you feel the need.
| oaxacaoaxaca wrote:
| For a good while I thought I was the only one who is against
| hooks. It's good to see there are two of us. By the looks of
| the other comments here, maybe even three.
| reactspa wrote:
| Hooks never grew on me.
|
| I pretty much stopped paying attention to new versions
| after React 14.
|
| KISS - keep it stupid simple.
|
| I suspect that some Devs new to JS didn't like the various
| definitions of "this", and Hooks was supposed to help them
| out.
| lhorie wrote:
| There are a number of people that dislike hooks, many of
| who are vocal in React threads. Basically the entire
| classes-are-fine camp do, and there are a few of us in the
| "the React team doesn't appear to understand the functional
| paradigm" camp.
|
| I fully expect that in a few years React will be widely
| seen as a J2EE-like poster child of over-engineering shark
| jumping for the functional paradigm. I already do.
| city41 wrote:
| I find hooks are best when used sparingly. I once worked on a
| project that went all in on hooks and some bugs were very
| hard to track down. Stale closures can be a headache too.
| I've been meaning to capture the gotchas I've seen into a
| website. Maybe I will one day. All in all, hooks get the job
| done but I'm not really a fan.
| gherkinnn wrote:
| It's tricky. I've had some nasty stale closure bugs too.
| The ESLint hook plugin fixes these, but I wish that plugin
| wasn't required. And some of the hook rules are puzzling at
| first.
|
| But, I've had way more annoying problems using class-based
| syntax. Twice the code, four times the pain. And TS type
| inference doesn't work as nicely with classes.
|
| Vue got it right in many ways. At least back in the 2.0
| days, the last I've worked with it.
| ng12 wrote:
| People can write bad code in any framework. If it's that
| difficult to uncoil declarative state in your head the
| component is poorly written, hooks or not.
| kabes wrote:
| Yeah, and sometimes it feels like I'm writing a really
| cumbersome dialect of javascript.
|
| I mean, something simple like: let i = 0;
| const inc = () => i+=1;
|
| becomes: const [i, setI] = useState(0);
| const inc = useCallback(() => setI(currentI => currentI +
| 1));
|
| Every single thing needs layers of abstractions upon layers
| of abstractions.
|
| For all the hate angularJS got, at least with dirty checking
| your javascript was just plain javascript. I'm leaning more
| and more towards svelte, which offers this, but more
| performant than with dirty checking.
| nathias wrote:
| What are you talking about? How did using classes instead of
| functions improve performance?
| mrloba wrote:
| In general a function component does a lot more work than a
| class render function. Some of it is just about handling
| cases that we probably should have done with classes as well,
| but often didn't. The result is that everything must be
| carefully memoized (or not, it's sometimes hard to predict).
| For example, should you memoize a redux selector function
| like useSelector(state => state.x)? Should you wrap every
| function in useCallback? With classes we had arrow methods
| that ran once, while useCallback will be run every time the
| function component is run. We have to continuously check that
| function references are stable, if it matters, and if we care
| enough to bloat the function with various memo calls.
|
| Now I'm not at all saying that class components are better.
| Hooks are mostly easier to work with. But there's no doubt
| that function components has me using too much brain power
| and lines of code on memoization. I like the new features the
| react team are working on, but I hope they'll eventually do
| something about the stable function reference problem as
| well.
| mtone wrote:
| The problem with useMemo is that it prompts using more
| useCallbacks to avoid triggering those memos and hell
| ensues. Any time I've battled against the flow of water the
| readability/maintainability cost got too high too fast.
|
| I don't work in very large apps so take with a grain of
| salt. My hard-won strategy has been to break down
| components a bit more, often just derived-state functional
| components for presentation, never modifying props, ensure
| sole state ownership responsibility, concentrate useEffect
| IO in few key components and never for logic, very limited
| uses of context, avoiding bloated libraries, and otherwise
| generally let it go.
|
| If that was to fail, I think I'd just consider something
| else than React.
| handrous wrote:
| Certain performance improvements and mitigations for common
| performance problems in something like React require bi-
| directional interaction of state and state-related events
| with _instances of_ components. Classes /objects are a pretty
| natural fit for that, obviously. To do the same with
| functions, you have to... re-create parts of a class or
| object system, which is what they did with Hooks.
|
| That would be the "all kinds of tricks" the OP referred to.
| Not that going from one to the other is inherently a win, but
| that to match the capabilities and ergonomics that classes &
| objects come with out of the box for addressing state-related
| performance improvements & state-related features, with
| "functional" React, you have to resort to "all kinds of
| tricks", i.e. write your own version of some of the OO things
| you _need_ to get the job done semi-cleanly (which is exactly
| what the React team did with Hooks).
|
| The result, to put it in only _slightly_ unfair terms, is
| that React has enabled their community to use a really bad
| and half-baked OO system with bizarre syntax & behavior, all
| so that no-one _has to_ use the "class" keyword sometimes.
| They didn't do that for funzies, but because some of the
| things they wanted to do, including things related to
| performance, _required_ OO-like features to be workable, but
| for whatever reason they didn 't want to rely on built-in
| language features for that, nor tell their community that
| _sometimes_ they would _have to_ use those built-in language
| features. Instead they opted for... Hooks.
___________________________________________________________________
(page generated 2021-09-29 23:02 UTC)