[HN Gopher] UIs are not pure functions of the model (2018)
___________________________________________________________________
UIs are not pure functions of the model (2018)
Author : b3morales
Score : 81 points
Date : 2022-07-04 17:07 UTC (5 hours ago)
(HTM) web link (blog.metaobject.com)
(TXT) w3m dump (blog.metaobject.com)
| eurasiantiger wrote:
| Funny, just yesterday I posted an in-depth comment concerning
| this exact topic.
|
| https://news.ycombinator.com/item?id=31968100
| hitekker wrote:
| > The idea of UI being a pure function of the model seems so
| obviously incorrect, and leads to such a plethora of problems,
| that it is a bit puzzling how one could come up with it in the
| first place, and certainly how one would stick with it in face of
| the avalanche of problems that just keeps coming.
|
| Richard Harris takes the same tact. He describes "UIs as a
| function of state" as an ideology:
| https://docs.google.com/presentation/d/1PUvpXMBEDS45rd0wHu6t...
|
| I think junior developers tend to invest in a single web
| framework and let their identities get tied up in the
| architecture of that framework.
| hombre_fatal wrote:
| > When I first saw React.js, I had a quick glance and thought
| that it was cool, they finally figured out how to do a Cocoa-like
| MVC UI framework in JavaScript.
|
| So smug that it's hard to take seriously.
|
| Especially when even Apple is switching to SwiftUI, something
| that is the opposite of Cocoa and more similar to React.
|
| Though I wonder how someone with both Cocoa and React experience
| looks at React and goes "Oh, it's the old-school Cocoa way of
| doing things!"
|
| This blog post reminds me of HN four years ago when everyone had
| their little smug epithet about Javascript and web developers,
| those idiots who are too amateur to see the beauty of Cocoa and
| winforms or whatever most of us are happy to swap with something
| better.
| atwood22 wrote:
| For what it's worth, a lot of developers I know who work on
| complex iOS applications have more or less abandoned SwiftUI
| after trying it.
| epicureanideal wrote:
| Why are they abandoning it? Could you please share reasons in
| as much detail as possible? Very interested to know.
| ardit33 wrote:
| It is fine for small toy apps (think the calculator), but
| it is missing a lot of functionality to build a full
| fledged app. Think collections, which is the backbone of
| most apps.
|
| UIKit is very mature and has evolved to a really good UI
| platform. SwiftUI is not even close to unseat it. Maybe in
| few years it will mature as well, but for now UIKit is the
| way to go.
| hbn wrote:
| I only ever played around with making a toy app while
| following along with Stanford's Swift UI course[1], and
| even just the basic things I was doing there, I ran into
| multiple frustrating/confusing bugs.
|
| As if it wasn't difficult enough to wrap your head around
| learning it in the first place, running into bugs makes
| it even harder because you think you're doing something
| wrong until you finally ask online and get told by people
| more knowledgeable than you, "I don't know why that's
| happening, wrap your view in a container and it'll work"
|
| [1] https://youtube.com/playlist?list=PLpGHT1n4-mAsxuRxVP
| v7kj4-d...
| interactivecode wrote:
| At Beam[0] we are building a web browser that uses
| SwiftUI almost everywhere except for the text editor.
|
| So far its been great to build UI and animations with.
| Each release gives SwiftUI more apis and features, so
| there are less and less older style apis to wrap in
| SwiftUI ourselves.
|
| [0] https://hellobeam.com
| kecupochren wrote:
| Those scroll effects are quite janky on iOS btw
| rudedogg wrote:
| It takes quite a bit to wrap your head around the SwiftUI way
| of doing things. I think a lot of people get frustrated and
| throw in the towel. I'm sure React is the same story.
|
| And while you can't do _everything_ in SwiftUI, it 's pretty
| solid and capable now. I only have a couple things using
| AppKit in a large macOS project.
| EGreg wrote:
| And now four years later they accepted the web developers but
| now are having smug epithets about Web3 developers, those
| idiots who are too idealistic to accept the beauty of Web2's
| centralized model
| kkarimi wrote:
| Agreed. If it was cocoa Apple wouldn't ditch their old ways to
| create a clone of react approach
| brundolf wrote:
| Agree that it's phrased really smugly and that detracts from
| the message, but important to note it's dated 2018, at which
| time React was very different than it is today and SwiftUI
| didn't exist yet
| [deleted]
| adzm wrote:
| I'd argue that React is pretty much the same now as it always
| has been. The ecosystem has matured and grown for sure but
| even the basic API has remained pretty much stable.
| brundolf wrote:
| Hooks didn't exist yet, for one, as mentioned in the Dan
| Abramov quote at the bottom:
|
| > we're adding a stateful function API as a preferred
| alternative to classes soon
|
| Class components were the focus at the time, and are now
| all-but-deprecated. Also, Redux was still very popular in
| practice, which it isn't so much now (partly due to hooks)
|
| That's a pretty big change in the way people use React,
| which certainly informs a discussion like this
| acemarke wrote:
| I'd have to disagree with this on a couple levels.
|
| Yes, hooks change the way we write React code in some
| ways, but in a lot of other ways nothing has changed. We
| still write components that accept props, have state, and
| return UI descriptions as JSX elements, and those
| components may cause side effects after a render is
| completed. Conceptually, the core principles of React are
| still exactly the same, and hooks didn't change that.
|
| Additionally, Redux is still by far the most widely used
| state management tool for React apps. My rough estimates
| are that 45-50% of React apps use Redux, whereas Mobx and
| XState are around 10-15%.
|
| I'll agree that Redux is not as "popular" as it once was,
| which is due to a number of factors. It was heavily
| overused early on, and the ecosystem has expanded to
| include a lot of other great tools that overlap with some
| of the use cases for Redux. But, "modern Redux" with
| Redux Toolkit is much easier to learn and use than the
| legacy hand-written patterns, and we get highly positive
| feedback on a daily basis from folks who tell us they
| enjoy using RTK. (In fact, RTK by itself has more
| downloads than Mobx, XState, or React Query.) So, that
| tells me Redux will continue to be widely used for a long
| time.
| pcthrowaway wrote:
| > My rough estimates are that 45-50% of React apps use
| Redux, whereas Mobx and XState are around 10-15%
|
| Curious how you arrive at these estimates? I would have
| thought fewer than 30% of React apps started in the last
| year or so use Redux, but of course, many still do,
| perhaps a higher percentage of apps that were built >2
| years ago do (you could argue these are more mature, so
| they've "grown into" redux, though you could also say
| they're legacy and preceded newer React capabilities and
| tooling)
|
| I don't have a strong inclination one way or the other,
| and have been toying with introducing Redux (or some
| other kind of state management) for the app I work with,
| but my understanding from the general sentiment of the
| threads/projects I follow is that market share of Redux
| has fallen in the last year or 2.
| azemetre wrote:
| Just looking at download trends redux is literally in a
| class of its own. What I do wonder is how often people
| are abusing context, state, and reducers to make their
| own terrible state managers rather than using redux? I
| bet that number is higher haha.
|
| https://npmtrends.com/mobx-vs-redux-vs-xstate
| systemvoltage wrote:
| > Especially when even Apple is switching to SwiftUI, something
| that is the opposite of Cocoa and more similar to React.
|
| Well, that's hardly a counter argument. The core argument
| should be whether "SwiftUI is better than Cocoa", and _not_
| whether a Big Tech company is switching to it unless we are in
| a popularity contest.
| hgsgm wrote:
| It's not smug to observe that someone ported MVC to JavaScript.
| It's a lot of work to build.
| jonkoops wrote:
| Except it's not MVC.
| pier25 wrote:
| React would be the V in MVC, no?
|
| I mean, even Vue takes its name from that (pronounced
| "view").
| lmm wrote:
| There are no controllers in the react way of doing
| things, or at least no separation between view and
| controller if that's your perspective.
| dan-robertson wrote:
| There were a lot of "MVC in JavaScript" frameworks before
| react. I don't think that's really a useful description of
| react or of the work or idea involved.
| mpweiher wrote:
| You might want to listen to Pete Hunt, one of the creators of
| react.js:
|
| https://futureofcoding.org/episodes/011
|
| 17:30
|
| "The core idea with react, and this is the only thing that
| matters, so don't view components as a react innovation.
| Components have been around forever. You build any sort of
| native application on Windows or macOS or iOS and there's a
| notion of component, some call it a view or whatever, but the
| idea of composing components out of other components has been
| around since the dawn of time.
|
| I don't know why we weren't doing it on the web. I think we
| were just, I don't know, being stubborn or something. But
| that's not a new innovation."
|
| Hmm...sounds just a bit like what they were trying to achieve
| was something along the lines of "Cocoa for the Web".
|
| But what does he know?
|
| -\\_(tsu)_/-
|
| Anyway, he does go on to say that the core innovation is having
| the UI be a pure function of some state. But that's the part
| that isn't actually true. It ain't a pure function. See Dan
| Abramov's comment:
|
| _Support for local state and side effects is absolutely a core
| feature of React components and not something we avoid for
| "purity"._
|
| So if it's not a "pure function" of the state, then it's some
| mapping of the state. All UI is some sort of mapping of the
| state, otherwise it's not really a UI.
|
| Hmm...
|
| So being a "pure function" of the state is not the innovation,
| because it isn't true, and being some mapping of the state is
| also not the innovation, because all UI is a mapping of the
| state.
|
| Hmm...
|
| So what is the _actual_ innovation? It is more or less
| _directly_ and _visibly_ expressing the UI in code. And since
| all our languages are essentially procedural (functional, OO)
| that means expressing the UI as a procedure (function /method).
|
| And so the "pure function of the state" turns out not to be a
| feature of this model, but a (squishy) requirement. Because in
| order to make the UI definition a procedure, you have to re-run
| that procedure at arbitrary times (and ideally also run it
| partially). And so the requirement is "sufficiently pure that
| we can re-run it".
|
| And that is an innovation, and it's kinda cool. But it does
| break down rather quickly, which is why all these frameworks
| keep iterating, and iterating, and iterating.
| zethraeus wrote:
| > since all our languages are essentially procedural
| (functional, OO) that means expressing the UI as a procedure
| (function/method).
|
| I understand 'functional' to be used as the direct contrast
| to 'procedural'! Is that not your understanding?
|
| > So what is the actual innovation? It is more or less
| directly and visibly expressing the UI in code.
|
| The 'visibly' part here doesn't really actually hold true,
| does it? Once you've componentized your <swiftui/react/html/[
| VFL](https://developer.apple.com/library/archive/documentatio
| n/Us...>, it's probably not super visibly understandable.
|
| The best definition i can think of for declarative UI
| frameworks is probably something closer to 'frameworks that
| optimize for your ability to make a pure function
| representing state'.
|
| (After all `[[UIViewController alloc] init]` does indeed
| purely say 'you have view controller' -- that's just not
| super granular!)
|
| In this light, isn't SwiftUI just a setup _more_ optimized in
| this direction
| stillkicking wrote:
| Thesis:
|
| >The application event loop coalesces these damage rectangles and
| initiates an optimized operation: it only redraws views whose
| bounds intersect the damaged region, and also passes the
| rectangle(s) to the drawRect:: method. (That's why it's called
| drawRect::).
|
| So, according to this, you need an explicit run-time mechanism to
| optimize the interaction of parents with children, with some form
| of coalescing.
|
| Antithesis:
|
| >This is another reason why it's advantageous to have a stable
| hierarchy of stateful objects representing your UI. If you need
| more context, you just ask around. Ask your parent, ask your
| siblings, ask your children, they are all present. Again, no
| special magic needed.
|
| ...except here, where OP says you don't need any special magic to
| deal with parent/child relationships: just reach
| up/down/left/right and do your thing!
|
| Synthesis:
|
| The reason one-way data flow became so popular is exactly because
| the second view is a trap, or at least, a local maximum. If you
| are really doing complicated orchestration in your hierarchy,
| then you will end up reinventing the first wheel, to avoid
| expensive/inefficient parent/child/parent thrashing cascades.
|
| React does in fact have a good solution for this, in the form of
| contexts. These also allow you to reach up and go talk to
| parents, in a controlled yet composable way. The way I describe
| them is "singletons but with scope". An underappreciated benefit
| is that you can extend a parent context and pass it down,
| replicating some of the benefits of inheritance, without the
| messyness of subclasses.
|
| Where React falls short is that parents can't respond to children
| without re-rendering themselves, which ironically makes
| implementing e.g. nested tree widgets hard, even though the
| result is all tree-shaped.
|
| Functional effect systems which can re-join after forking, and
| gather yielded values, do not have this issue, and I wish React
| would explore this avenue instead of the all the React 18 stuff
| they've been doing lately... it feels too much like they are
| leaning into the same Facebook "dumb read-only UI" style that the
| article correctly laments. They are straying away from React's
| original appeal, which was that it was "just the V in MVC", and
| instead becoming very opinionated on how server side and client
| side should be combined. Meanwhile the challenges of how to
| replicate complex legacy desktop UIs remain mostly unaddressed,
| with the official advice about event handlers, state and effects
| falling short by a mile.
| thurn wrote:
| Every non-trivial (>10k lines) Cocoa/iOS/Android application I've
| ever seen or worked on has re-implemented at least some parts of
| React's data flow model. It's surprising to me that the author
| glosses over handling lists, which is a huge challenge with this
| approach, and one that forces you to do some React-like stuff
| (UITableView cell recycling identifiers!) even if you don't want
| to.
|
| However, there are definitely _some_ problem domains that don 't
| map very well to the React model. Real time games, for example,
| have very different requirements.
| chowells wrote:
| Even real-time games are often best implemented as a pure
| function of state. This has a lot of advantages for keeping
| track of everything, especially in games with a network
| component. Of course, it doesn't mean the function from state
| to UI doesn't get to use mutable state - that's often critical
| for performance. What's important is logically separating the
| game state from the UI, such that any game state can be
| isolated, serialized, and de-serialized at will.
| crooked-v wrote:
| I've had a very silly project in progress for a while along
| those lines to implement a Game Boy emulator entirely in
| Redux (state) and React (screen output, with pixels mapped to
| the appropriate bits). If I ever finish I imagine it will be
| incredibly slow, but it would allow for 'time traveling' the
| entire emulator state.
| elwell wrote:
| I explored a little what it would mean to use pure functions
| to generate state for a game that has a little physics: https
| ://github.com/celwell/wordsmith/blob/master/src/cljs/wo...
| madeofpalk wrote:
| on the other hand, AppKit/UIKit has UITableView/CollectionView
| view recycling just built into the framework, whereas everyone
| on web (including React libraries) is trying to reimplement it
| in userland
| manmal wrote:
| Lists are IMO the only area where imperative style has the
| upper hand - you can build truly endless lists because items
| are loaded lazily. UITableViewCell identifiers are cell _type_
| ids, not cell ids btw, so they pose no overlap with React.
|
| If you need a very long list in React, you need to use a
| library with quite weird API.
| the_gipsy wrote:
| The author could really benefit from trying out Elm.
| zethraeus wrote:
| I spent a while trying to approach this post with an open mind.
| In the end I was disappointed.
|
| rel/to title: yes. (just say scroll position. fine.) But also I
| think this is pretty well understood! (No?)
|
| - In declarative UI / FRP / whatever, you model your basic UI
| state through a pure mapping from your business logic 'model'.
|
| - But (as in procedural programming) the UI has its own state --
| that's not necessarily part of your initial
| business/domain/model.
|
| If you want to model it, you'll have to understand it, read it,
| and add it to you model. That can be annoying--especially if the
| APIs for getting or setting the state are bad.
|
| This doesn't really sound like a fundamental flaw conceptually to
| me. It's just an API with defaults you don't have to deal with
| unless you _need_ to.
|
| - don't care what your color is? fine. system default for you.
|
| - don't care what tab a link opens in? fine. user default.
|
| - don't care how scroll position is managed? fine. system
| default.
|
| - _want to handle any of them? cool. you can._
|
| It sounds like progressive disclosure of API complexity to me.
| Great.
| zethraeus wrote:
| (And of course FRP setups have to iterate! They're refining the
| model to declaratively represent 20 years worth of UI
| convention!)
| brundolf wrote:
| Needs a (2018)
| Latty wrote:
| > We do not make the (unwarranted) assumption that this
| transformation can or should be expressed as a pure function.
| While that would be nice, there are many reasons why this is not
| a good idea, some pretty obvious.
|
| So obvious they are left as an exercise for the reader?
|
| This whole article seems to be based on the idea that pure
| functional programming is absurd and impossible, and this is just
| obvious and doesn't need to be shown. For someone who has written
| a decent amount of Elm, it certainly isn't obvious to me.
| mpweiher wrote:
| > This whole article seems to be based on the idea that pure
| functional programming is absurd and impossible
|
| Huh? Where?
| origin_path wrote:
| The article is explaining those reasons, which the author feels
| are obvious but he spells out nonetheless. The gist of his
| argument is that because UI is not a pure function of a little
| pile of centrally defined state, React has to come up with lots
| of new concepts and mechanisms to wallpaper over the conceptual
| gap. Hence his table which by the end is boiling down to "OOP
| toolkits don't need this" alongside explanations of very
| complex FP approaches.
| zosima wrote:
| This is interesting, mostly because to me it reads as a typical
| blub paradox type response to react.
|
| http://weblog.raganwald.com/2006/10/are-we-blub-programmers....
| draw_down wrote:
| No indeed. However the UI does emit changes to the model as the
| user interacts with it. These can be modeled as a series of
| values over time, aka a stream.
| dsego wrote:
| > A UI is NOT simply a replication of server / business logic
| state.
|
| I don't think that was ever the claim, the rest of the article is
| similarly misguided. UI as a function of state doesn't mean "UI
| is a function of business logic state". It means we define the UI
| in a declarative way based on the view state.
| ridiculous_fish wrote:
| Yes, the article makes that assertion on behalf of both React
| and Cocoa and explores the different way they address that
| problem. It uses "scroll position" as an example: scroll
| position is typically not tracked in the React state, so how
| does it work?
|
| In Cocoa, scroll position is part of the view's state, a mere
| property of the view. This is simple because the UI itself is
| stateful.
|
| In React, scroll position is typically not part of the state
| from which we project the view. Instead this state is attached
| to the projection itself (e.g. a HTML node) and we are
| dependent on the "Memoization Map" to preserve it. So this
| memoization is now required for the correct functioning of the
| app. The "pure function" abstraction is leaking.
| mwcampbell wrote:
| > A core premise of Cocoa, and MVC in general, is that UIs are a
| projection of data into a different form of data, specifically
| bits on a screen.
|
| This is a tangent, but the implicit assumption that the UI is
| visual is just begging for a response from an accessibility
| perspective, so here goes.
|
| Accessibility is very much an afterthought in native GUIs, not
| only in Cocoa, but also in Windows with the UI Automation API,
| and AFAIK with other native accessibility APIs as well. With
| these APIs, the assistive technology (e.g. screen reader) pulls
| information from the application (usually via the GUI toolkit),
| through repeated calls to methods defined by the accessibility
| API. Often the AT has to do several such calls in a row (and
| those often translate to multiple IPC round trips, making things
| slow). And the UI might change between such calls; there's no
| guaranteed way to get a consistent snapshot of the whole thing,
| as there is with a visual frame. On the application/toolkit side,
| these methods may return different responses from one call to the
| next, and the application or toolkit has to fire the right events
| when things change.
|
| The web improves on this, in that accessibility information is
| conveyed through HTML tags and attributes. And yes, this is
| included in the output of a React component's render function. So
| while in practice, implementing accessibility may still be an
| afterthought, it's not an architectural afterthought as it is in
| native platforms.
|
| One of my goals in AccessKit [1] is to work around this
| shortcoming of native accessibility APIs, particularly for
| developers of cross-platform non-web GUI toolkits. In AccessKit,
| the toolkit pushes a full or incremental accessibility tree
| update to the AccessKit platform adapter, which maintains the
| full tree in memory and uses that to implement the platform
| accessibility API. This even works for immediate-mode GUIs, as
| one can see in my proof-of-concept integration with the Rust egui
| toolkit [2].
|
| [1]: https://github.com/AccessKit/accesskit
|
| [2]: https://github.com/mwcampbell/egui/tree/accesskit
| paulryanrogers wrote:
| React components built as div soup may actually be worse for
| accessibility than thoughtfully written no-JS HTML.
| wonnage wrote:
| This statement is practically a tautology
| andrewingram wrote:
| And no-JS HTML built as div soup is likely worse for
| accessibility than thoughtfully written React. So React
| itself has no bearing on it.
|
| My take is that it's the growing complexity of web
| development (yes, React has some responsibility here),
| combined with the constant influx of new developers, that's
| largely to blame for any overall proportional loss in the
| practice of accessible markup.
| ksbrooksjr wrote:
| I agree. Another thing to consider is that React makes it
| frictionless to import custom components, instead of
| attempting to re-write common UI patterns from scratch.
|
| If a React dev leans on an accessible UI framework like
| Chakra, or Headless UI, or React-Aria, they're probably
| better off from an accessibility perspective than a dev
| that tries to implement WAI guidelines from scratch.
| saulrh wrote:
| And? The point of the parent was that _either_ of those are
| better than native - doesn 't matter how much div soup you
| have, at least the information exists, unlike the bucket of
| raw pixels that're all you get from native UIs sometimes.
| paulryanrogers wrote:
| Desktop UI frameworks are a bit of a mess. Though truly OS
| native should be the most accessible of all.
| origin_path wrote:
| This is a good counter-argument to the React proposition. It's 5
| years on, and both Apple and Google are now adopting the model
| for themselves via SwiftUI and JetPack Compose, but, is it
| actually the best way to do things?
|
| If you're used to toolkits that give you a basically fixed set of
| components, in which creating new components is considered an
| advanced operation and there's no assistance with data binding,
| then something like React seems like a breath of fresh air. I've
| done a bit of JetPack Compose, and also some JavaFX and of course
| HTML5 stuff. On the web React is an upgrade simply because the
| DOM isn't meant for UI and HTML has no notion of components at
| all. On Android, well, the classical Android UI toolkit was never
| that great. It's a Java Swing era API with three different clock
| classes in it! I can't comment on UIKit, never used it.
|
| Maybe a better comparison would be to something like JavaFX,
| which pre-dates the crazy for functional programming but
| benefited from the years of experience with classical toolkits
| like Swing/GTK etc. And here, it gets hard to really get excited
| by React. The blog post isn't wrong - the React model requires a
| ton of concepts, abstractions, and complicated infrastructures to
| try and recreate things that come for free in OOP toolkits.
| JavaFX supports data flow and binding because every property is
| both observable and bindable via lazy dataflow graphs. So your UI
| can indeed be a pure function of the model, but instead of re-
| execute/cache/memoize/diff, you assemble the computation graph
| for whatever needs to be reactive. Most of the time, you don't
| actually need to do anything complicated here and can write code
| as a straightforward imperative calculation.
|
| Creating components is likewise pretty easy, albeit JavaFX is
| currently in a sorry state where the open source community around
| it doesn't maintain the documentation properly, so it's hard to
| link to a tutorial that demonstrates this. But basically you get
| a pay-as-you-go approach in which you can just group some widgets
| in a class, or you can be a bit more ambitious and inherit from
| Control which gives you things like proper focus/tab order
| management, the ability to control properties using CSS and so
| on.
|
| When I read code written with JetPack Compose, the feeling it
| gives isn't really that great compared to the OOP style. The way
| it totally changes the core programming model of the language
| looks like an absolute nightmare to teach to new programmers. The
| most fundamental rules of the programming language are suddenly
| up for grabs - what looks like straight line imperative code
| actually isn't, variables might retain their state beyond the
| scope of a function call ... or might not ... and it seems like
| React/Compose codebases invariably degrade into tons of tiny
| functions passing giant amounts of stuff around on the stack,
| with lots of obscure performance problems that come from the game
| playing with the core execution model and all the
| diffing/patching going on behind the scenes.
|
| In the end I find I agree with the author. Good UI is not in fact
| a pure function and the FP model is a poor fit. There is too much
| implicit state that is best encapsulated in the UI framework, and
| with an actually well designed OOP framework data binding just
| isn't painful enough to justify the costs.
| revskill wrote:
| Of course, we can put a launchMissiles inside useEffect, so of
| course UI is not pure function of model in React. That's why
| there's PureComponent in React which disallowed state or effects.
| ridiculous_fish wrote:
| It's not about useEffect. If a Component renders a text field,
| that text field has additional state (e.g. cursor position)
| which is not part of the model. That's one reason why the UI is
| not a pure function.
| ptx wrote:
| Couldn't this be solved by acknowledging that there is
| application-domain state (such as the value of the text
| field) and UI state (such as the cursor position and
| selection), which can be represented by an application-domain
| model and view model respectively, rather than trying to
| pretend that the latter doesn't exist?
|
| Although if you model all the UI state, maybe you just end up
| with the DOM?
| ridiculous_fish wrote:
| Yes, this is known as MVVM.
| https://en.wikipedia.org/wiki/Model-view-viewmodel
| Kaze404 wrote:
| This feels like saying Haskell doesn't have pure functions
| because they don't account for cosmic ray bit flips.
| ridiculous_fish wrote:
| No, this implicit state is a very practical concern in
| React. For example see this highly upvoted SO post. Text
| fields lose focus on re-render; the solution is to use a
| unique key so that the view gets re-used and the implicit
| state is preserved.
|
| https://stackoverflow.com/questions/22573494/react-js-
| input-...
| jarjoura wrote:
| In my experience, object oriented view systems like Cocoa (UIKit
| or AppKit) work great for small teams with deep domain knowledge
| of their code base. However, they constantly require refactoring
| as teams grow and systems become more complex. This leads to
| overly complex UI code over time that become brittle.
|
| UI through composition, building UI through assembling components
| from other components, has done away with those issues. The
| enforced encapsulation is frustrating that I agree is a trade
| off, but refactors become simple find and replace to point to new
| components instead of having to rewrite entire chunks of
| previously working code.
| andrekandre wrote:
| > UI through composition, building UI through assembling
| components from other components, has done away with those
| issues.
|
| it should be noted, you can do this just fine in cocoa/uikit
| with delegation/message forwarding etc. but most people dont
| know about that ime
|
| lots of subclassing and overriding is much harder to avoid with
| view controllers but view-level subclassing is usually an anti-
| pattern _(if i got a dollar for every time i found a
| "RedButton" class id be a millionaire)_ but like most things
| people aren't either experienced or educated enough in these
| frameworks > However, they constantly require
| refactoring as teams grow and systems become more complex. This
| leads to overly complex UI code over time that become brittle.
|
| i think this becomes true with any system, but subclass-heavy
| code makes it definitely harder imo > ...is
| frustrating that I agree is a trade off, but refactors become
| simple find and replace to point to new components instead of
| having to rewrite entire chunks of previously working code.
|
| if done well it is easier in swiftui for sure, but the way i
| see people write "in the real world" swiftui is used in a much
| more monolithic fashion and hard to pull-apart... (personally i
| love swiftui) but i think real-world usage will still he
| mudballs in a large portion of codebases (there is no silver
| bullet)
| lmm wrote:
| > lots of subclassing and overriding is much harder to avoid
| with view controllers but view-level subclassing is usually
| an anti-pattern (if i got a dollar for every time i found a
| "RedButton" class id be a millionaire) but like most things
| people aren't either experienced or educated enough in these
| frameworks
|
| At some point if the system guides everyone into doing it the
| wrong way, it's a problem with the wrong system. Subclassing
| is rarely the right solution, one of the things that's really
| refreshing about React is that most people tend to naturally
| avoid subclassing when using it.
| origin_path wrote:
| nemothekid wrote:
| > _Except for games, UIs are actually very stable, more stable
| than the model. You have chrome, viewers, tools etc._
|
| I think the author's analogy breaks down here. Almost every point
| after this is "You don't need this because React started from
| this faulty assumption that UIs aren't stable".
|
| The hand rails frameworks like React gives you is because this
| assumption isn't true. If your UI is stable enough where this
| complexity isn't needed, then _don 't use React_.
| adamnemecek wrote:
| I have been thinking about this a bunch lately and I think that
| the main problem with all these approaches is that it's all built
| on top of a DOM and as a result it gets us to a local optimum and
| prevent us from reaching a global optimum.
|
| The thing that these approaches don't account for is the
| rendering aspect which should ideally be done on the GPU.
|
| There's this duality between Array of Structs and Struct of
| Arrays [0]. People find programming with Array of Structs easier
| but GPUs work with Struct of Arrays. I think that a language is
| needed that fundamentally compiles AoS to SoA.
|
| Another advantage is that repainting the whole scene is much
| cheaper do you can be a lot more aggressive with repainting
| everything.
|
| [0] https://en.wikipedia.org/wiki/AoS_and_SoA
| Marazan wrote:
| Takes me back to the time when MVC zealots absolutely lost heir
| shit when React came out.
|
| React obliterated their world view and they simply could not
| cope.
|
| I am using hyperbolic language but the "Anti-React" 'backlash'
| was truly mind boggling.
| vbezhenar wrote:
| I'm not computer theorist. But to me React seems like a perfect
| implementation of MVC. Model is state. View is virtual-dom
| chunks. And controller is an actual function implementation
| which maps state to view.
| [deleted]
| elanning wrote:
| This is typically a good way to organize React projects, in
| my experience. A few top-level components which hold state
| with a useReducer and have a few functions to make backend
| calls, as needed. You could consider the reducer the model
| and the top-level component the controller. All components
| that sit below the top-level are pure view components. Props
| in, view out. They at most hold a minor amount of UI state.
| They don't make API calls or update state themselves, that
| must be done with a callback to the top-level component.
|
| This makes testing simple as you can test the reducer without
| rendering any UI. The pure view components are also easy to
| test. Then a few end to end tests to tie everything together.
|
| https://www.reactguide.dev/#mc-v-trees Has more info on how
| to scale the pattern for larger apps.
| My104thaccount wrote:
| FinalBriefing wrote:
| I'm still one of those people. Separation of concerns is a big
| concern for me.
|
| In my experience with React, it's a lot harder to keep things
| separated, and developers who I've worked with who have more
| React experience aren't always up on the concept.
| Jakobeha wrote:
| A UI can be represented as a set of concurrent/asynchronous
| prompts. UI takes the model and possible next actions, presents
| this to the user, gets a response, and returns this as an action
| which is then applied to update the model.
|
| Alerts and login forms are clearly prompts. But so is an complex
| editor: it constantly prompts the user for the next action, e.g.
| enter text or change existing text's formatting. Or a social-
| media site: possible actions are "login", "view post", "create
| post", and so on.
|
| Even an FPS can be warped into a prompt-based UI, where the model
| is the game state (or what the player sees of it), and the
| prompts are "move, turn, shoot". But you probably shouldn't do
| that. Asp bad examples: a weather or stock viewer where your
| options are null, and the model is the weather or stock which you
| can't change.
|
| Nonetheless prompt-based UI is really useful for many otherwise-
| ordinary cases. It lets you write a UI like a CLI and automate
| your UI very easily; it tells you which state is truly part of
| the "model" and which is just part of the UI; it's composable
| spatially (more elements) and temporarily (series of steps). I
| don't know if it's been explored much.
|
| In prompt-based UI, the UI is _sort of_ a pure function of the
| model. It's an asynchronous function which takes the model and
| returns a stream or future of the next action(s).
| projektfu wrote:
| I think there are a lot of specious comparisons. In Cocoa, all
| parts of the UI can theoretically participate in the app and be
| wired in the same way. In the web, you don't get your own text
| field, etc, so you will have to make do with what's there. Thus
| there will be parts that have to be handled differently.
|
| I think Marcel brings up a valid point about composition, if I
| understood it correctly. The composition of interfaces in Dolphin
| Smalltalk, for example, is super easy with the MVP paradigm. You
| can build and test a particular feature and immediately drop it
| into another, larger composite presenter. You just make its model
| a field on its owner. Other properties can be connected to where
| they need to be during the initialization of the component.
|
| I'm not sure if wiring up react components is as easy, because
| you have to think about stuff that is not directly in your data
| flow. But I honestly don't have enough experience to say. I have
| more experience with Elm and found it a little less easy.
|
| At that point, the big difference between MVx and reactive is the
| bidirectional data flow in MVx. Parts need to be bound so that
| they update the real world, and updates need to be observable so
| the UI can change. Reactive UI coordinates a filtration of that
| state through the view painting.
|
| In Elm (old Elm, not sure what it's like now) when you embed a
| component your top level needs to understand its messages to pass
| them down/up appropriately. The type system helps you not forget
| things, but there was a good bit of retyping.
|
| That, and the way that html bits fit into other bits breaks the
| abstraction. Perhaps using a reactive approach to run Web
| Components is the best way to get the same sort of composability
| currently, I haven't tried it.
___________________________________________________________________
(page generated 2022-07-04 23:00 UTC)