[HN Gopher] It's time for a data-first front end revolution
       ___________________________________________________________________
        
       It's time for a data-first front end revolution
        
       Author : feross
       Score  : 82 points
       Date   : 2021-05-18 15:17 UTC (7 hours ago)
        
 (HTM) web link (kea.js.org)
 (TXT) w3m dump (kea.js.org)
        
       | devilduck wrote:
       | It's time to make UI a separate job to "front end".
        
       | mdoms wrote:
       | Isn't this the normal way of React with Redux? It's how I've seen
       | it done for years.
        
       | pcmaffey wrote:
       | This boils down to the original confusion around hooks. Putting a
       | sequence of useData / useState hooks inside a View component is
       | just as "data-first" as wrapping a View component in HOCs for the
       | api and app state.
       | 
       | Ultimately it comes down to how you structure your components.
        
       | 1shooner wrote:
       | I remember this when it was XML -> XSL -> HTML.
        
       | boxed wrote:
       | It seems like the article is talking about Elm.
        
         | holtalanm wrote:
         | Yeah, now that you mention it, yeah. Elm is the natural
         | progression down the functional programming rabbit hole for the
         | frontend. Either that, or ReasonML, which I haven't seen much
         | news for recently.
        
           | niels_bom wrote:
           | They renamed Reason to Rescript, FYI. (I don't actively
           | follow Reason or ReasonML, but the rebranding caught me by
           | surprise).
        
         | yakshaving_jgt wrote:
         | Basically the rule in front-end land is to keep poorly
         | reinventing stuff that Elm has done elegantly for years without
         | much fanfare, all the while pretending that Elm doesn't exist.
        
       | cutler wrote:
       | Honestly, why not just use Clojurescript if that's where the
       | inspiration came from? With Clojurescript/re-frame you don't have
       | to think about which of the myriad useX inventions apply to your
       | app. Every couple of years React seems to be throwing-out more
       | clutter (hooks, forms) just to get a bit closer to what
       | Clojurescript + re-frame has had for years.
        
         | blunte wrote:
         | When some organization gets serious about providing complete
         | ClojureScript education and tutorials, especially covering the
         | setup/config challenges... and then keeps those current so the
         | examples always work, then this could be a reality.
         | 
         | But as long as a newbie has to piece together their own
         | solution from many optional libraries and build systems, the
         | initial time investment will dissuade people from taking the
         | plunge. Of course, an established Clojure shop has already
         | gotten over this hump and can easily onboard and bring new devs
         | up to speed.
         | 
         | If the Clojure world never realizes they need to get serious
         | about providing quality education, then Clojure will decline in
         | use relative to other options. It's a shame.
        
         | pvorb wrote:
         | Because you will reduce the number of potential candidates for
         | hiring by one or two orders of magnitude, even if it might be a
         | technically justified choice.
        
           | yepthatsreality wrote:
           | This is always touted as a reason but honestly I always spend
           | time teaching the hired new frameworks, JS knowledge,
           | ecosystem knowledge, etc. The world already operates on
           | multiple languages and JS is already an exhausting confusing
           | ecosystem. There's no reason not to use something because
           | it's in a different language.
        
         | napsterbr wrote:
         | Strong plus one. Not to mention that I often see highly
         | experienced frontend devs writing components that re-render
         | itself on every change, just because it's so easy to make the
         | mistake of unnecessary re-rendering on modern React.
         | 
         | Developing with re-frame means you re-render only when data
         | _actually_ changes, with almost zero chance of making
         | accidental re-renders, and no need to spend mental energy on
         | "should I wrap this with useCallback or useEffect?".
        
           | mariusandra wrote:
           | Something that comes for free with Redux and its abstractions
           | like Kea (the approach promoted in the linked blog post) is
           | that you mostly avoid the problem of needless re-renders.
           | 
           | Each `useSelector` call (and `useValues` call that uses it)
           | triggers a re-render only when the value changed. So unless
           | you have something forcefully re-rendering the root node,
           | only the few relevant sub-sections of the page will re-
           | render.
           | 
           | It's not perfect nested-sub-object level precision, but in
           | practice works well enough.
        
         | kgwxd wrote:
         | I feel the same way, but it could be a really big commitment to
         | choose ClojureScript for a lot of projects. I have my own shop
         | and haven't had an opportunity where I felt comfortable
         | suggesting it, even though we have a few devs that would love
         | to use it.
        
         | EastLondonCoder wrote:
         | ClojureScript is great and it'd be my first choice if
         | performance doesn't matter. For me the drawbacks are that
         | bundlesizes tend to be bigger than using js. Profiling is much
         | harder due to the output from the google closure compiler is
         | somewhat opaque. Reasoning about memory allocation and leaks
         | can be quite difficult even in a complex js app, having
         | persistent data structures makes this an order of magnitude
         | more difficult.
        
       | timdaub wrote:
       | I've been developing small scale react applications since 2015.
       | Application state has seldom been a problem for me.
       | 
       | Initially classes were a problem as they made unit testing
       | harder. I'm happy react moved towards functional logic.
       | 
       | Integration tests were hard because there was no good one-stop-
       | shop framework. I now use cypress and it's OK.
       | 
       | Tooling was hard as there was a bazillion options and nothing
       | stood out. I now use esbuild. It's pretty good.
       | 
       | I once made the mistake to use redux to fix a problem I didn't
       | have, namely handling application state. Then I tried MobX.
       | 
       | These days, I mostly use component state and a REST api. For
       | reusable components, I create an npm lib. Whatever.
        
       | fishtoaster wrote:
       | I suspect this is right.
       | 
       | I've been with the JS world long enough that I've seen a lot of
       | the major iterations - each solving the problems of the last.
       | 
       | - Jquery solved the browser inconsistencies and limitations of
       | vanilla JS
       | 
       | - Backbone added MVC structure to large, disorganized soups of
       | Jquery
       | 
       | - Angular + Ember gave you a more full-featured MVC so you didn't
       | have to rebuild common logic on top of every backbone app.
       | 
       | - React switched to a component-oriented architecture as we
       | realized that MVC wasn't a great fit for frontend.
       | 
       | I think the next big problem that will be solved by the next big
       | JS change is that organizing and interacting with your data layer
       | is a pain. Redux is complex* and is a ton of overhead for a lot
       | of use cases. Tools like React-Query make handling one kind of
       | global state easy, but do so by mixing it up with the view layer.
       | 
       | A strong contender for the next dominant frontend approach
       | (whether that's a single framework, a data layer that works with
       | react, or a new set of tools) will be one that really tackles the
       | data layer well.
       | 
       | * Redux actually really simple at its core, but it's such an
       | incredible ton of boilerplate that everyone inevitably builds
       | their own complex and bespoke tools for dealing with it.
        
         | qudat wrote:
         | > Tools like React-Query make handling one kind of global state
         | easy, *but do so by mixing it up with the view layer.*
         | 
         | This is where I think `react-query` fits a very specific niche.
         | I see a lot of new projects reaching for it and while I think
         | for simple applications it can work fine, I have a serious
         | problem with it for large applications: it's baked into react.
         | React is a view layer that is slowly consuming the world and
         | while I don't think react is going anywhere, people are
         | starting to feel the burden of a black box system.
         | 
         | As someone who's primary job has been building large scale web
         | applications for the past 7 years and has weclomed the chaotic
         | nature of the FE ecosystem, I'm starting to feel a little less
         | optimistic about react's future.
         | 
         | That's why the allure of something like redux is so strong for
         | some of us. Redux is not that complicated and the boilerplate
         | has mostly been reduced to a few lines of code.
         | 
         | React is continuing to grow in complexity with hooks, suspense,
         | async rendering, and now server components. I think for
         | personal projects I'm probably going to reach for something
         | else like Svelte.
        
         | pogorniy wrote:
         | > one that really tackles the data layer well
         | 
         | I believe this should be rxjs. It's composable: have a stream
         | or streams create new derived streams easily. It's lazy: you
         | can describe what to do with data before it's available.
         | Handling state for the multi step or async operations (loading
         | state, cancelling requests, retrying operations) is a breeze.
         | "Wire" your application with rxjs and you'll never have trouble
         | modelling state with it. Typescript-friendly. It allows be both
         | sync access to the value (BehaviourSubject) and async
         | (Observable). I work with it closely last year and there was no
         | situation I could not model with rxjs.
         | 
         | But people will stick to whatever is hyped by well-known-
         | internet-company. Marketing wins, not quality.
        
         | kgwxd wrote:
         | Of everything I've used over the last 20 years, nothing has
         | felt more simple than re-frame[0].
         | 
         | It's built on React but it's ClojureScript, so it probably
         | wouldn't be an easy option where already invested in another
         | ecosystem, but it's a real pleasure to work with if you can,
         | especially if you buy into the tooling for your editor and
         | browser.
         | 
         | [0] https://day8.github.io/re-frame/re-frame/
        
         | acemarke wrote:
         | Note that we created our official Redux Toolkit package [0]
         | specifically to solve the "boilerplate" concerns. It includes
         | utilities to simplify several common Redux use cases, including
         | store setup, defining reducers, immutable update logic, and
         | even creating entire "slices" of state at once. The "Modern
         | Redux with Redux Toolkit" docs page [1] shows how to migrate
         | from hand-written Redux logic to use RTK's APIs.
         | 
         | We've had a ton of very positive feedback from folks who love
         | using RTK, and even from folks who didn't like Redux before.
         | 
         | Also, we're currently finalizing a new "RTK Query" API for
         | Redux Toolkit [2] that provides a purpose-built data fetching
         | and caching abstraction layer, which basically eliminates
         | having to write any of your own code to fetch data. That's
         | available now in the RTK 1.6 alphas [3], and we hope to publish
         | that live shortly.
         | 
         | [0] https://redux-toolkit.js.org
         | 
         | [1] https://redux.js.org/tutorials/fundamentals/part-8-modern-
         | re...
         | 
         | [2] https://deploy-preview-1016--redux-starter-kit-
         | docs.netlify....
         | 
         | [3] https://github.com/reduxjs/redux-
         | toolkit/releases/tag/v1.6.0...
        
       | dzonga wrote:
       | Higher Order Components work well for what's described. But they
       | were thrown out of the window.
       | 
       | And yeah, all the rage is hooks which also will soon be thrown
       | out the window.
        
         | postalrat wrote:
         | The only thing stopping you from writing higher ordered
         | components is you. If you are not maybe you found an
         | alternative you prefer.
        
           | yakshaving_jgt wrote:
           | No, it's the job market that dictates what people write.
           | 
           | It's frustrating that people I care about who are going for
           | entry-level positions will fail an interview because they
           | didn't demonstrate usage of the interviewer's pet favourite
           | reinvention of some basic UI development concept.
           | 
           | Oh! You used Redux and you didn't use hooks! Sorry, no job
           | for you.
        
       | ChicagoDave wrote:
       | If you design a set of views to act as a part of a particular
       | domain, then this will lead to API's for that domain and that
       | functionality.
       | 
       | The data you view and the data you store is just communications
       | and absolutely should be last.
        
       | deckard1 wrote:
       | It means going from:              Frontend > React > [state
       | management library of choice]               to
       | Frontend > Data Layer > View Layer (React)
       | 
       | This is MVC, no? That's basically the diagram for MVC on the
       | Wikipedia page.
       | 
       | I suppose giving it a "-first" (god I hate this trend) moniker
       | spiffs it up a bit. We could also name it "modern MVC" for
       | ultimate internet points.
       | 
       | I'd also read this article (not mine):
       | 
       | https://chriskiehl.com/article/react-as-an-implementation-de...
       | 
       | Pay attention to the caveats. Specifically:
       | 
       | > The complex pieces usually warrant it, the simple ones usually
       | do not. There's nothing original or revolutionary in these ideas,
       | they're often just forgotten.
       | 
       | And that's probably why we do React with ad hoc Redux today. It's
       | the path of least resistance. Why think about boring business
       | rules and how to model them with lots of tiresome boilerplate
       | when you can just throw up a prototype in React. You could
       | probably fit a good argument of why so many people reach for
       | NoSQL over SQL in there too.
       | 
       | Ultimately, all code starts simple. So you're screwed from the
       | start. Only later do realize your code is a mess and your lack of
       | modeling is causing chaos everywhere, from one-off TypeScript
       | interfaces _everywhere_ to lots and lots of null checking.
        
         | nicoburns wrote:
         | React and MVC would be a pretty good mix I reckon. I did some
         | early React projects with Backbone.js instead of redux and it
         | worked pretty well.
        
       | qudat wrote:
       | Data is always first with redux + redux-saga. I haven't used
       | reframe but have read the documentation a number of times. redux-
       | saga seems like a pretty great alternative that is very popular
       | in the react/redux world.
        
       | moshmosh wrote:
       | FTA:
       | 
       | "It means going from:                   Frontend > React > [state
       | management library of choice]
       | 
       | to                   Frontend > Data Layer > View Layer (React)
       | 
       | "
       | 
       | I'm not really sure what "Frontend" means here, but I'm pretty
       | sure this is how I was using React + Redux, back when I was
       | developing in that ecosystem a ton. I certainly wouldn't diagram
       | it as the first example.
       | 
       | The hard part with doing this "purely" is that it'll murder
       | performance for text inputs and animations. All this developer-
       | centered convenience comes at a performance & resource-use cost
       | to the user, it's just most-obvious when you're dealing with
       | forms and animations.
        
         | zdragnar wrote:
         | Having also been in that area, I almost never put forms or
         | animation state into the redux store. Sure, you lose a certain
         | amount of time-travel goodness, but it made for a much saner
         | development experience (especially where performance was
         | concerned).
        
           | acemarke wrote:
           | Yes, we specifically recommend that most "form state" should
           | _not_ go directly into Redux:
           | 
           | - https://redux.js.org/style-guide/style-guide#avoid-
           | putting-f...
           | 
           | - https://redux.js.org/faq/organizing-state#should-i-put-
           | form-...
           | 
           | In other words: it's fine to take data that's in the Redux
           | store, use that to initialize a React form, do the form
           | updates in local state, and then dispatch an action
           | containing the final results when the form is complete. But,
           | there's almost never a good reason to dispatch a Redux action
           | on every keystroke. You don't need to track that level of
           | granularity in the Redux DevTools, other components in the
           | app are unlikely to need to see those individual updates, and
           | it's a waste of update and subscription handling.
        
             | Joker_vD wrote:
             | By the way, about that "dispatch an action containing the
             | final results when the form is complete" -- what is the
             | Correct Way(tm) to do this, if there may be several
             | instances of the form? They should produce different
             | actions so that different pieces of state would be updated.
        
               | acemarke wrote:
               | "It Depends"? :)
               | 
               | Typically if you've got a single React component type
               | that is supposed to be reused in multiple places with
               | differing behavior, the right answer is "pass in
               | something as a prop". In this case, that could be a
               | callback function that dispatches the correct action, so
               | the form component can just do
               | `props.onFormCompleted(data)`, and the differing usage
               | sites can pass in different callbacks that dispatch
               | different actions.
        
             | arenaninja wrote:
             | If only my PMs had cared...
             | 
             | I previously worked on a monstrosity where the input state
             | was owned by the backend via huge incomprehensible metadata
             | updates. Every keystroke had to be submitted (and thus
             | actions fired) because a field update could invalidate
             | other fields on the grid and the user could feel the
             | latency (~400ms roundtrip?) between each keystroke. The
             | backend team was sure they had discovered some magic sauce
             | and I noped out of there before my next bonus
        
           | moshmosh wrote:
           | Yeah, you basically _can 't_ do that without wrecking
           | performance, which is why I think attempts at more
           | "functional purity" (which, LOL, React has now entirely
           | abandoned anyway, see: hooks) and "single-source-of-truth"
           | than what's currently the norm in the React world (or
           | anywhere else in FE web dev) are misguided.
        
             | zdragnar wrote:
             | I still prefer a global store and keeping functions as pure
             | as possible. I just make a distinction between application
             | state and ephemeral (i.e. local state such as drag / drop
             | tracking, forms, etc).
             | 
             | There _are_ a number of advantages to centralizing your
             | event handling pipeline and using middleware functions to
             | perform many of the more important side effect producing
             | behaviors (i.e. analytics events, etc.).
             | 
             | YMMV though, and I now that I am working on an app that
             | makes extensive use of hooks and useContext, I cant say
             | that the world has ended (even if it is quite a bit more
             | confusing).
        
       | zackify wrote:
       | State management in Frontend really is a solved problem if you
       | know what you're doing.
       | 
       | Use a tool like swr, react-query, or Apollo-client.
       | 
       | I personally use graphql and my front end client manages most of
       | the global state automatically.
       | 
       | Change a field, and it updates in other components.
       | 
       | Simple local state for modal transitions and other routine
       | logic... and that's all I need.
       | 
       | Every week there's a new article bashing front end complexity
       | with redux as the scape goat.
        
         | mariusandra wrote:
         | Agreed that if your frontend is mostly GraphQL, and your data
         | flow well taken care of, you shouldn't see a need for a
         | separate state management solution.
         | 
         | However sometimes you have to work with various APIs and
         | filter/display/modify/update/delete/change/patch various parts
         | of the responses you receive. That's the environment where
         | solutions like Kea (mentioned in the blog post) come into their
         | own.
        
         | alexjray wrote:
         | You summed it up perfectly, react-query aims to literally solve
         | this exact problem.
         | 
         | It does it quite well I might add.
         | 
         | React, Mobx etc are all reactive frameworks exactly for this
         | reason. Given a set of data render x, update the render every
         | time the data changes.
        
         | yonixw wrote:
         | Flux and MobX are good if you don't want to fetch the server on
         | every action or if you have a lot of cross references inside
         | the data layer.
        
       | scarmig wrote:
       | Only vaguely on topic: what's the current state of the art around
       | offline-first apps with data syncing? Particularly, something
       | that works like PouchDB, with local databases for web and mobile
       | clients that sync to a centralized source of truth.
        
         | bmuon wrote:
         | The industry is definitely dropping the ball on offline. To
         | give us credit, legal/privacy issues don't make it easy.
        
       | holtalanm wrote:
       | https://xkcd.com/927/
       | 
       | seems relevant.
       | 
       | On a more on-topic note -- this data-oriented structure seemed to
       | be at the core of the goals of Vue 3, to the point where you
       | don't even need to use their Flux implementation, Vuex, anymore
       | for 100% vue3 projects.
        
       | yoran wrote:
       | > By following a few principles of immutability and purity, React
       | frontends were generally better written, stabler and easier to
       | debug, compared to contemporary alternatives such as Ember or
       | Angular.
       | 
       | I have the exact opposite experience. Our large Ember application
       | is a lot more maintainable, and requires a lot less boilerplate
       | code to get things done, than this React Native app that I'm
       | working on.
        
         | holtalanm wrote:
         | completely agree. every React app that I have ran across that
         | used 'best practices' for React development has been an
         | unmaintainable dumpster fire.
        
         | jordache wrote:
         | I concur.
         | 
         | Angular's framework contains all the baked in patterns that is
         | friendly for a large enterprise scale application.
         | 
         | DI, Angular Modules, opinionated patterns.
         | 
         | More boiler plate yes, but small, one-time cost to pay, for a
         | scalable pattern that the entire community subscribes to
        
       | austincheney wrote:
       | Application state is a trivial problem to solve. Even better is
       | that if you figure it out once you can carry the experience
       | forward to any other project.
       | 
       | The only reason people perceive this to be a real concern is
       | because they have never done it without a framework.
       | 
       | https://github.com/prettydiff/wisdom/blob/master/state_manag...
        
         | pogorniy wrote:
         | > Application state is a trivial problem to solve.
         | 
         | This is very interesting. Can you show example which you
         | believe trivially solves state?
        
           | pogorniy wrote:
           | Nevermind. I saw the code by the link.
        
       ___________________________________________________________________
       (page generated 2021-05-18 23:02 UTC)