8 ms·
Before React: to make a transition, let's change this, this and then that, mutating state on every step. After React: have one pure function, which takes as inp
by xixixao 11y ago
Before React: to make a transition, let's change this, this and then that, mutating state on every step.
After React: have one pure function, which takes as input the current state and produces the desired output.
This is the main shift. It's very similar to how imperative programming is done in Java vs Haskell.
- vezzy-fnord 11y agoAre they pure? I don't think JS has any way to guarantee referential transparency, though of course the use of a virtual DOM can mitigate side effects by having well-defined behavior. Furthermore, the input-process-output model can hardly warrant being called "functional" in of itself, unless you really want to overload the term. The React way of independent handlers that trigger events which incrementally calculate state and update views, is, in fact, quite similar to how Smalltalk UI paradigms work, right down to the installation of an event handler resembling a message send operation. If you don't believe me, check out the Morphic framework that Self uses to implement its environment UI. The similarities are striking: http://handbook.selflanguage.org/current/morphic.html http://handbook.selflanguage.org/current/morphic.html
- xixixao 11y agoIf they are not pure, you are literally making an error (as the framework states they are supposed to be pure). input-process-output is how pure functional languages (such as Haskell) deal with imperative coding. You push the imperative part to the top of the call stack and try to keep the rest of the computation pure. JavaScript inherited quite a bit from Smalltalk, so you will find similarities like these in JS in general. Flux supplements the standard React bubbling of events up the chain of components with a simpler, singular flow, making it even more functional.
- vezzy-fnord 11y agoThat sounds like a try-hard simplification. Input-process-output is pretty much a generic metaphor for programming in general. I don't think React has anything like monadic encapsulation (not that a language like JS can conveniently accommodate it). You're observing a few high-level properties of a given paradigm and extrapolating an inferred architecture solely from those points. In fact, you're equivocating the entire management and abstraction of mutable state as an inherently "functional" thing, which it is not. OO is just as much capable of factoring state as a virtual resource that you explicitly make transitions to and from and transparently or visibly share increments across object boundaries, as this is exactly what e.g. Self does with Morphic, right down to the same event handler structure. Just because one is a lambda and the other is called a method doesn't make a huge difference. I'm saying that just about all of React's insights were done previously almost verbatim in thoroughly object-oriented environments. That some FP evangelists have a kneejerk hatred for it doesn't mean the mental gymnastics for insisting one over the other is necessary. They can be complementary.
- peterhunt 11y agoI haven't used Morphic in years (and I used it in Squeak). While you're right that Morphic shares some things in common with React, the fundamental difference is that when a composite morph receives an event and needs to change, it has to explicitly pass messages to all of its submorphs to transition them to the next state. With React you simply throw out the old subtree and replace it with a new one. This is similar to how drawOn: works, except that throwing out and re-instantiating your submorphs for every drawOn: is expensive and loses UI state. React gives you this abstraction. Additionally I'm not sure where you're getting this "JS can't be functional" opinion from. Just because it doesn't give you compile-time or runtime guarantees, or because the syntax may be more clunky, doesn't mean you can't get these benefits by convention.
- vezzy-fnord 11y agoAdditionally I'm not sure where you're getting this "JS can't be functional" opinion from. I never said this. I was talking more about the React architecture, specifically. Though in general there is this phenomenon to grasp at any similarities and start espousing how functional a particular language/framework/library is, as if for street cred.
- xixixao 11y agoBut I haven't written that input-process-output equals functional. I just pointed out that the React model allows for a larger piece of the code to be functional, in exactly the same way it's done, say, in Haskell. This has nothing to do with monads. Monads are used for the imperative, stateful code that is pushed to the top of the call stack, the bit which is partially managed by React for you (by calling the render method). I would also never claim that React invented any of this. It just popularized this more declarative approach for building Web UIs
- stream_fusion 11y agoI thought your analogy was spot on. In React, the view is reduced down to a functional projection of the model - rather than being a complicated set of state interaction patterns (eg. mvc,mvvm). The React framework then handles the real DOM update - in the same way that a Monadic IO computation is not executed directly - but instead is passed to the Haskell IO runtime to be executed.
- shostack 11y agoCan you dumb this down slightly for an "early" developer with a real world example by any chance? I'm not grokking the significance of why changing everything and having mutations is bad.
- orthoganol 11y agoIt's just nicer to use if you have complex UI. OP's response was poor IMO, just because something follows some abstract principles doesn't necessarily give it value for us. I'll give you examples of things I've worked on where React made sense & where it didn't: -E.g. use React (or Backbone, Angular, etc.): A real-time document editor, with many interacting components, with lots of real time updating of the UI. Definitely needed a framework like that, and it was great. -E.g. don't use React, because in these cases it's a total Rube Goldberg machine (extra steps to achieve the exact same outcome): Basic web app with some ajax submissions, adding results to DOM type of stuff. Maybe small html fragments cloned, inserted by jQuery. No extra fancy client interactivity. ^If people claim you should use React for the latter (undoubtedly some will), they are very likely just people who follow trends to follow trends, or maybe don't have a ton of web experience and it's one of the few things they've learned and are sticking to. It's just so unnecessary (not to mention 100kb+ of overhead, & in my experience comes out to about x3 the amount of code). But yeah, absolutely use React if it's anything like the first use case.
- hodwik 11y agoWhat technologies would you prefer for the latter case?
- meestaahjoshee 11y ago"Basic web app with some ajax submissions, adding results to DOM type of stuff. Maybe small html fragments cloned, inserted by jQuery." regular old html and jQuery + ajax.
- xixixao 11y ago1) React does not make simple apps overly complex. It might feel like more work if you are more used to jQuery. If you are used to React instead, it really won't have a huge negative impact on a small app. 2) React will scale. It will be a much better vehicle for future development (as you admit, it is more suited for more complex cases than jQuery). I was not making a judgement on the value of the approach, although I personally believe that this paradigm shift has a huge positive impact and is applicable in lots of cases. If I can choose between lots of computation intertwined with state mutation and a declarative approach where the mutation happens on the smallest scale, up the call stack, I will always choose the latter (of course, unless you have to mutate to gain performance).
- barrkel 11y agoBefore React: to make a transition, let's change this, this and then that, mutating state on every step That's nonsense. There have been data binding frameworks used for well over a decade in JS development - I know I wrote one in the early 2000s. You can't write a decently sized app in JS without developing something like data binding, unless you love busywork and bugs, or have zero prior experience of what came before in GUI frameworks. Data binding is designed exactly to prevent the need to explicitly mutate all the views at every point that the model can change. Instead you write bindings that project the model into the view, and make the model reactive, so that changes to it propagate automatically. It's the same in any decently sized Backbone app - that's why the Collection and Model give you all these events. What's new in React is the idea of cheaply creating a virtual DOM and extracting a set of diffs from it that can then be applied to the real DOM. I did something vaguely similar, again in the early 2000s, but the motive then was to reduce the amount of data on the wire (the server had a data-bound model of what was displayed on screen, but only sent diffs back to the client). It's a neat idea and an excellent implementation, but it's not original or groundbreaking.