6 ms·
The fundamental magic of react is that it lets you write code that renders O(n) UI states in a functional manner (i.e. by returning the HTML you want) rather th
by lihaoyi 2y ago
The fundamental magic of react is that it lets you write code that renders O(n) UI states in a functional manner (i.e. by returning the HTML you want) rather than O(n^2) UI state transitions in a mutable manner (by mutating the page via nested callbacks), and somehow makes it kind of fast-ish
People love complaining about React, but I don't know if they remember the pre-React world where you had to write the code to manage O(n^2) UI state transitions via recursive mutating callbacks. Simple things like "have a the list of photos shown always kept in sync with a label showning count of photos" was incredibly error prone, and the complexity of implementation went up quadratically with the complexity of your app (due to the n^2 state transitions you needed to worry about!)
Today React is not the only one to do this O(^2) to O(n) complexity reduction, but it was the first to go mainstream, and very much deserves its success in spite of its various shortcomings
- hasanhaja 2y agoHow are you getting to O(n)? Is that in terms of the logic you need to read and keep in your mind? Or is it the actual computational complexity?
- teddarific 2y agoAm curious on the O(n) calculation as well haha — I get what OP is saying, but would love to know if there's some deeper technical details here.
- lihaoyi 2y agoThe basic idea is if you have n ways your page can display, with the old PHP/CGI whole page refresh model you needed to write n endpoints, but every interaction required a slow and disruptive whole page refresh With pre-react single page apps, if you had O(n) ways your webpage could display, you needed to write code to account for n^2 ways that each of those n states could transition into another one of those n states With react, you write code to render n pages, and get the fine grained interactivity for free with good (enough) performance. It basically removed a tradeoff/dilemma that had been facing web developers since time immemorial, so no surprise it was a big hit
- fleabitdev 2y agoYou're completely right, but I think it's worth adding that the O(n^2) to O(n) change isn't specific to React or UI. That same improvement is often seen when migrating other code from a mutating style to a pure-functional style. "A pure function which transforms the entire input into the entire output" is obviously the simplest possible architecture for many programs, but people hesitate to use that architecture because of performance concerns. In practice, the baseline performance is often faster than they expect, and it can be made much, much faster using strategies like memoisation and fine-grained reactivity.
- lihaoyi 2y agoWe've been doing the O(n) thing forever with PHP and CGI since 1995, the issue is that it required constant whole-page reloads and was a poor experience that got worse the more interactive your webapps got. React let you do the same thing but made it fast(ish) with local updates We actually see similar innovations on the FP side as well, with persistent data structures that allow structural sharing so your "copy and update" operations can be fast enough to be usable (even if still not nearly as fast as in-place mutation)
- nox101 2y agoReact doesn't have this "pure function" feature what-so-ever. hooks are magic stateful functions, not pure functions. They behave differently the second time called and therefore have all kinds of side-effects and restrictions on when, where, and how they can be used.
- srcreigh 2y agoAccumulative recursive functions also behave differently the second time they are called... Hooks are a declarative DSL for accumulator arguments to the recursive function (the component). If you would rather rewrite the render loop in continuation passing style, and have a 46 line recursive call expression which conditionally changes like 15 immutable parameters to set up the next render iteration for your component, I'd like to see the code when you are done.
- antris 2y ago
- codeptualize 2y agoThis. I still have nightmares sometimes. If you don't use a framework you will probably end up building one, and it's not going to be as good as the existing options.
- nox101 2y agoI don't know if I'm convinced. I have several react projects stuck in dependency hell. If I upgrade from build in node 18+ (from 16) I start getting errors. If I try to upgrade react then 1 of the 3 external widgets I'm using barfs out. If I do manage to get upgrade I get complaints about all the best practices from react 16 that have been deprecated. If I'd written my own all of these issue would disappear because I wouldn't have made breaking changes to my own framework. Note: you might say node 16 is old and I agree. I'd much rather be on 22. But since I can't get out of this dependency hell without days or weeks of work the projects have been stuck for years.
- codeptualize 2y agoThen do it.. you are free to experience it. Especially if it’s just you on the team you might be totally fine. I will just say that any project that lasts that long will require maintenance work now and then. The issues you describe seem quite minor and are probably relatively easy to patch up. React provides code mods that do a lot of the heavy lifting, your external widgets have updates, or alternatives. I would also add that you don’t have to use dependencies with react. It’s always good to be mindful of dependencies and limit them. It’s the same thing, you choose dependencies to save you time, or you do it yourself. My main point is that with your own framework you will also run into limitations, causing big rewrites taking days/weeks/months, and/or lots of upfront cost..
- crabmusket 2y agoI never want to go back to a non-declarative rendering framework. Does anyone remember a blog post from maybe 2016-ish which described the process of "building your own" react-like rendering loop? I remember it being a fantastic explanation of what the virtual dom is and does, and why the "UI is a function of state" paradigm is great. I remember it having a live example to the right side, with prose and code on the left. I can't for the life of me find it now :(
- retropragma 2y agoThis? https://pomb.us/build-your-own-react/ https://pomb.us/build-your-own-react/
- crabmusket 2y agoSadly not. I did find this article too while searching for what I remember. It is a close match in so many ways, but also not quite. I remember the article very much taking the approach that you've never heard of React before, and walking through a series of problems and discoveries like "oh, what if we just render the state to the DOM every frame? let's see how that works". Almost like a "you could have invented React" kind of vibe. I think there was a button-counter demo app.
- WA 2y agoNot a live preview and not a button-counter demo at the end, but the overall structure and the whole O(n) vs O(n^2) argumentation was in this blog post from a now defunct domain. Maybe this is what you were looking for: https://web.archive.org/web/20150414080539/http://hackflow.com/blog/2015/03/08/boiling-react-down-to-few-lines-in-jquery/ https://web.archive.org/web/20150414080539/http://hackflow.c...
- crabmusket 2y agoThis definitely looks different, and I don't recall seeing this before. But this is a great post! It communicates some of the very important ideas in a straightforward way. Thanks!
- yawaramin 2y agoYou should check out htmx. It goes really well with ScalaTags :-)
- lihaoyi 2y agoScalaRx and Scalatags actually works a lot like React.js, in user-facing experience even if not in implementation. Unfortunately I was just a college kid and couldn't push it the same way the pros at Facebook could push react!
- Joeri 2y agoReact isn’t that special. You can do a react-like design in many frameworks, and in fact you can even do it with vanilla web components. The code ends up a bit more verbose and ugly, but it still has that o(n) core design. To give an idea, here’s a video I made where I port react’s tic tac toe example to vanilla web code. https://youtu.be/bhvNvQA2oqA?si=bJYZYAU8uueb-6ST https://youtu.be/bhvNvQA2oqA?si=bJYZYAU8uueb-6ST And here’s a more advanced example that preserves input field focus and uses a context: https://github.com/jsebrech/vanilla-context-and-reducer https://github.com/jsebrech/vanilla-context-and-reducer