[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)