• she/her 🏳️‍⚧️

I can’t work the loom, Tone

.kaybee on Discord

💖 @saralily 💖


wavebeem
@wavebeem
warning: longpost incoming

a quick note

i'm reflecting on 10 years of react here, good and bad. i want to be 100% clear that i've been a web developer professionally for over 10 years as well, and i deeply love the web. do not show up in the comments assuming i hate the modern web like so many nerds on this site love to do loudly and frequently. yes, a lot of things stink about the modern web, but a lot of things are super cool about it too. also, this is not the time or place to discuss that. i'm also not interested in discussing electron or native app development. oh, and if you think "javascript was a mistake" or some other hot take, keep scrolling. please do not try to change the subject here as i'm not interested in discussing that with most people.

it seemed so cool

i remember back in like... 2014 when i was first looking into react, i was quite excited. besides the initial surprise of jsx syntax, it really seemed so cool to me.

what are they up to now?

react's public release turns 10 years old this month, and it's wild to think about its rise to power. a purely frontend js library is not spending absurd amounts of effort to somehow increase its backend performance, i guess. i'm not really up to speed on server components, and i'm still reeling with the fact that they rely on javascript string "pragmas" like "use strict"; all over again 🙃

how about jsx

at this point the jsx problem is moot. like sure it's still not part of the official JS grammar, and likely never will be due to the strange ambiguity of what the jsx function is in any given scope being a nightmare, but the tooling is certainly here a decade later and it provides unparalleled type safety and refactoring for your "templates", in my experience.

bundle size

it's interesting to see preact exist at literally 10% the size of react, while maintaining all the most important features (opinion!). it's been wild to see the rise of next.js as the de-facto fullstack js framework.

lasting impact from react

it feels to me like react finally put the MVC (model view controller) pattern to rest for frontend libraries for the most part. i think the web dev community has gotten less precious about having a million tiny files that each do almost nothing, resulting in a web of confusing awful code.

the component model chooses to slice code in a different direction, one that i think makes it easier to make the kinds of changes we want to do more often, and increases discoverability of code.

it also feels like react really pushed js even further toward functional programming, or at least state without direct mutation. js + react is nowhere near as pure as like elm for example, but it's honestly surprising how much react moved the needle here.

a not-so-stable target

it's been wild to watch as react has never really come off their initial release cycle. back when the framework was 0.x, they just released huge changes constantly. i expected some stability when they finally broke past 0.x, but no, they just release new major versions all the time. oh and they still don't correctly support web components! i blame react's popularity and refusal to reinvent their shitty event system with the absurdly delayed adoption of web components. like no they're not perfect but react is definitely hurting the situation.

jsx is cool

i remember having to learn sooo many templating languages. i won't lie and say jsx isn't a templating language, but critically it's an embedded templating language. allowing us to use the host language (js) gives us so much power, and frankly colocating the html and js together is a huge boon for understanding how a lot of stuff ticks.

i also love that jsx has a strict syntax unlike html. jsx is the dream of xhtml for html, to some extent. i want unclosed tags to be a compile error, dangit! and i finally get that here. i'm sure other frontend frameworks have probably figured it out with extra tooling here and there, but i love that i get immediate obvious feedback about these issues with jsx and always have.

also, shout out to mithril js for doing the jsx thing before jsx with their awesome m function. that was cool and way ahead of its time. it inspired me to write about react sans jsx.

what about css-in-js

i'm so tired of hearing that react forces or even encourages you to use css-in-js. it does not!! i think it might be a natural conclusion to react's enforcement of colocating js and html, but it's not required. i remember feeling pure disgust when i initially saw css-in-js. then it evolved a bit and i saw emotion for js. this was actually highly useful on a library project i made at work. i loved it for that. and i allowed it to be adopted on our main site. and i quickly saw how it sucked in a larger context and in a mixed context with some regular css and some css-in-js. and the tooling is still annoying.

at this point, though, with ubiquitous access to css custom properties, the massively more powerful than css-in-js and natively browser supported feature, there's really no need to use these libraries. i want to see us go back to basic css and use custom properties when we need runtime values. for everything else, data-* attributes are fantastic for styling hooks. i'll admit though that in larger code bases it is nice to have some automatic namespacing via something like css modules, since it's hard to trust many engineers at scale to carefully manage a global namespace like css.

remember class components

it's so wild thinking about how react is so old that it originally used class components before js even had native classes. and their own class creation helper function allowed mixins! something that modern js classes do not support directly. i kinda hate mixins because they're too hard to understand and don't encapsulate well. that being said, there was a simplicity to class components with the named lifecycle methods and the ability to use this.state as a simple reference to updated state, even when dealing with nasty async/event stuff. and if you ever wanted stale data on purpose, it was easy to copy that state to variables you captured via closure.

anyway, i'm not surprised that react ditched mixins, but it's a bummer that hooks took so long to show up as their replacement.

react hooks

i blame the design of react hooks for countless programming errors. the authors of that feature clearly assumed that the common react programmer wouldn't absolutely buckle under the weight of understanding and working with variable closures in async and event handler contexts. i think they were wrong to make that bet. other frameworks like vue have taken that idea and run with them. in particular im excited about solid.js which takes inspiration from knockout.js's observables, which are still my favorite reactivity system i've used.

something about hooks just strikes me as a programmer feeling very clever about themselves. react function components were already weird but i guess technically they were state free and actually were functions. but now functions are actually classes in disguise, and jeez they were not built for that. there's a lot to be said about object oriented programming and how variable closure with record interfaces is analogous to classes and instances and whatnot, though that's not what's happening here. react just manages a secret state for you that it injects. oh yeah, like angular 1.x! remember how confusing that was. first js library i absolutely struggled to wrap my head around haha.

remember when it "wasn't accessible"?

i remember folks blaming react for not being accessible because it "forces you to use divs", which was genuinely hilarious. like yes for a long time every component had to return a dom element, such as a div, as the root... but nobody was forcing you to use components in a certain way! also, to my knowledge, adding extra divs rarely impacts accessibility, as long as you're not adding them in invalid places that will mess up your markup, like as children of a <ul> for example. don't do that.

we use react too much

i think it's a bummer we all use react as much as we do. there are lots of good options for web development. and i miss server-side html. i'm glad that next.js is helping us go back to that direction sneakily while letting us keep our react. though i think the design of react as a fullstack framework feels kinda sus. i realize this is a hard problem, though. i know a lot of people want a return to progressive enhancement, where js only adds some sprinkles on top of a fully server side html-based form-based website. i think that's good and well in theory, and it does make your system more resilient, but frankly people expect web apps nowadays, not websites. half the stuff i've seen people complain about on cohost are because it isn't app-y enough. we want js modals rather than full page refreshes. we want to share and scroll at the same time. we want to like and cruise by. and frontend js is how you do that, period. full page refreshes are a bummer. but still, we use react too much. hopefully we can see a future where less and less js is shipped unnecessarily to the browser, but like, capitalism.

haha this post is about capitalism now. surprise, bitch!

ok so i wanna be clear that like a lot of what people hate about the web is not because web developers are morons or lazy or whatever but that the software we use is made under capitalism. i care so fucking much, and i'm constantly divorced from my ability to improve things because economically it's not worth it. you realize that accessibility isn't prioritized because it's cheaper to pay off the occasional lawsuit than it is to spend more engineering hours fixing it, right? it sucks, but capitalists will view everything as a financial spreadsheet, and not as a moral choice. "nobody got fired for using jira" is now true for react as well. you know how easy it is to hire someone with react experience? everyone knows it now. hiring employees that already know a lot about your tech stack cuts down on onboarding, which is the period where new employees make the least revenue for you, thus costing you the most money. companies that use less popular technology have to settle for on the job training, mostly. imo it's not a huge deal and most good developers will pick up the new skills easily if they're not extremely brand new, but also not everyone is a good developer, and businesses still want to minimize risk.

sorry for the long post

i don't normally post this much about tech or post posts this long here. sorry i just got kinda... reflective looking at the react wikipedia page today. maybe this is a topic i'll want to put on my dot com blog at some point, though cleaned up.

i have a hard time letting go of perfection on that site, whereas unedited rants like this feel perfect for cohost. but still i think it's worth thinking about what has and what has not worked in react in the last decade.

quick note (again)

i'm reflecting on 10 years of react here, good and bad. i want to be 100% clear that i've been a web developer professionally for over 10 years as well, and i deeply love the web. do not show up in the comments assuming i hate the modern web like so many nerds on this site love to do loudly and frequently. yes, a lot of things stink about the modern web, but a lot of things are super cool about it too. also, this is not the time or place to discuss that. i'm also not interested in discussing electron or native app development. oh, and if you think "javascript was a mistake" or some other hot take, keep scrolling. please do not try to change the subject here as i'm not interested in discussing that with most people.

 

loading...

P.S. wish i could block tags. i'm still so tired of seeing #web development is a fucking nightmare every time i tag something for web dev and #fuck javascript too.


You must log in to comment.

in reply to @wavebeem's post:

Great writeup!!

something about hooks just strikes me as a programmer feeling very clever about themselves

yes!! and there was no need to make useEffect... like that. overall I like React and it's my go-to when I have to do something "for real". I only started with React in 2018, so by the following year all my understanding of the class structure was obsolete, but I think they were too much overhead anyway.

With the hooks now I can make every component be under 100 lines which is about the limit of what I can model in my mind accurately at any one time, and this was kinda hard with classes.

@ wavebeem: nice writeup :) thxx

@ both of u: honestly I'm interested to hear more detail about what people don't like about react hooks / useEffect because they came pretty naturally to me. unsure if this is a functional programming background or what but yeah, if yall wanna elaborate I'm all ears :) I'm mainly interested because like I study programming languages so it's always interesting to hear what pain points people have

The context for why I singled useEffect is thus: first, a lot of people used useEffect as a sort of initializing function for their components. Basically it's where they put the API calls and whatever that the component needed.

In React 18, though, the React team made useEffect fire twice when used with an empty dependency array "as a warning" that this will be the expected behavior of useEffect once a future, as-of-yet unreleased system is introduced. This system will persist state through mounting and unmountings.

Because they wanted people to stop using useEffect in the way I described before, they added this behavior even though there's no reason right now for it to behave this way. The whole attitude just gave me a rotten "we know best" vibe, and the implementation struck me as... I don't know, it's just icky to try to change people's behavior that way rather than communicating with them. I don't know, I just don't want my libraries being inconsistent as a way to "train" people to use the library "correctly". The fact that people are using the hook "wrong" means there is a feature that React needs and doesn't have, and people are working around that gap. Maybe they could have taken into account the way people use the hook right now and consider the use-case to be legitimate.

Of course, it's not like useEffect is unusable-- you can make it so that it doesn't fire more than you need or you can turn off strict mode-- but it was just a weird roadblock that they added for abstract reasons.

ps: i'm working off of recollections and emotional memory so i may be inaccurate in some places.

@wowperfect thanks!!

yeah i think a big part of this is the community was already trained to initialize state via async network calls inside componentDidMount which is somewhat similar to useEffect(fn, []) but not 100% the same, and then the react team got angry about it.

frankly, computing derived state in componentDidMount was never a good idea, because it's not reactive. so i see where the react team was coming from, but yeah the "debug mode" you mentioned really caused a lot of havoc.

i think that useState is actually the main problem here, and there's prior art for how to deal with computed state, especially in the old library Knockout which i loved.

i think useCallback especially is a big red warning flag, and the whole thing feels like "problems with hooks? you're not using enough of them" rather than making something that's easier to write to begin with.

at the end of the day, react does virtually nothing to assist you with async and event based code, despite those being ubiquitous JS paradigms.

and that stinks! because async and event based code are hard, and leaving everyone to solve the problems themselves is NOT working out in my experience.

The fact that people are using the hook "wrong" means there is a feature that React needs and doesn't have, and people are working around that gap

i think programmers don't want to grapple with the concept of developer UX (aka DX). you can have a powerful API that's hard for new people to use correctly, and hard for people to learn how to use correctly, and that's a bad DX. it feels to me like too many language and library devs kinda get this "its backend work" mentality that frankly annoys me. react is for humans, not compilers. at least that's my take. and if react is for compilers or meta-libraries, that should be stated clearly so more people can try to replace it or build on top of it to make something more useful.

thanks both of yall!! yeah I don't talk about this much in posts but I'm specifically interested in developer experience so it's helpful to read this kinda stuff.

also I very much agree with yall in terms of the lack of async/await integration into react. I feel like they promised Readers (?) or something at conference a while ago and said "these are coming Soon(tm)" and then it just didn't happen

yeah the new use(value) function seems to be their solution, but i'm really anxious because it looks like hooks yet specifically doesn't follow The Rules of Hooks, and it still doesn't solve async stuff alone... it requires that your async functions are now memoized! which, wow, memoization, jeez, has that ever been tough for people before? yikes. not hopeful for it tbh.

To be honest, I kinda consider React hooks to be a case of "used insufficient magic". They created something that allowed them to shuffle state into functional components (pulling from how Lisps do dynamic scope, no less), but damn if it doesn't have a lot of caveats.

Funnily enough, useState hasn't given me a ton of trouble yet, though I pretty quickly move to reducers, or a stateful "service" that projects out into hook state on change once more complicated logic gets involved. I think why I'm not tripped up is because I'm constantly aware of hooks as being, well, insufficient magic.

it's not like useState directly as the problem, it's the way it interacts poorly use await and event handlers more than anything for me.

and while yes i'm painfully aware of the warts i need to work around, i sadly can't be everywhere all at once and lots of ill advised code piles up in my absence.

i forgot that certain lisps use dynamic scope. i always associate with bash which is where i first learned it. and then in my first programming language i accidentally implemented dynamic scope! which was pretty funny to realize

@tati thanks!!

i totally love hooks in theory, to be clear. i just think the specific tiny details didn't work out so well, and i'd kinda love to see "hooks 2" based on all the other stuff that's been going on in open source UI frameworks.

it kinda feels like whatever Facebook-specific mindset they had testing hooks internally just didn't pan out in the real world, and maybe they could've used a longer public testing period before committing to the API

FWIW while I will never ever defend useEffect, i actually think that useState is the real culprit. i wrote a blog post about useState, and i think proxy-based state like in Vue and Solid are absolutely the way to go in the future

https://www.wavebeem.com/blog/2022/01/25/why-i-don-t-like-usestate/

Happy to see a post that’s balanced about react/Frontend frameworks! I think, like you said, the problems with a lot of these things come from the constraints of working under capitalism and not the tools we choose to use. It almost seems taken-for-granted these days, but JSX, components, and the way it structures applications were huge game changers! I even think the model of hooks is good, even if the implementation is screwy sometimes

thank you!! i really want cohost to be the platform for nuanced discussion that it's clearly capable of being (in stark contrast to twitter, for example), so i'm trying to lead by example 🫡

as a webdev, it is so refreshing to finally see some actual reflection on the state of things, rather than just "uhhh you use javascript? in your website??? cringe...". like yeah it's a mess sure, but like... it's our mess, y'know? sure it gets really hairy at times, but overall we've done pretty well to get to a point where it's as simple as it is to just spin something up and get a pretty functional Thing. the point on jsx stands out to me - jsx is the best experience i've had with templating-type thingies. the idea that components are just functions over input (props) that produce DOM trees just makes So Much Fucking Sense to me, and it's been a lot easier for me to wrap my head around than things like svelte, which i want to love but i just haven't spent enough time getting used to it's template system after all my time in react land.

overall yeah this is one of The Most Chosts on this website. thank you for sharing these thoughts

i love "it's [my] mess"!

i think one of the most frustrating things i see is "it's so hard to make a website now" as if someone is forcing you to make a full stack next.js app or something for your home page. and like there are so many free tools for making even a full HTTPS site online with CI/CD. or you can just use neocities! like idgi. i maintain sites that are just pure HTML pages all the way up to fully client side react code. it just depends.

exactly! sometimes you need plain ol' HTML. sometimes you need a whole ass SSR framework complete with a distributed, relational database. sometimes you need something in between. sometimes it's just personal preference! do what you want! make things! we have the tools to make things! they're not perfect sure, but they work well enough that the Whole Got Damn Tech Industry feels it fit to base their whole ass existence on them. and like you said - you only need to go as far as you think you need to. no one's forcing you to use graphql, or serverless functions, or nosql databases. but they're there if you need them.

Great post! I'm not sure what I could add but basically the same feelings on everything here that I had significant opinions about. I kinda miss coding in React, been having to solely work with salesforce stuff(ie LWC), ah well...

Also, a couple years ago I wrote this old thing about prop passing strategies, any fun comments on that like if certain patterns have come to the forefront? https://docs.google.com/document/d/1LBzSWQyMcS9AWmhV8TqFJFNst7nuMFgRutJzwDjQF-c/ Just randomly curious since its on topic, dont have to say anything if not interested

oh, i've never heard of LWC, but it's web components! i'm kind of a fan of those. sad to hear it's not a fun time for you. hmu if u wanna talk about it.

from your linked doc, i tend to go for 1, 3, and 6 mostly. sometimes 4 but i generally avoid it. and redux i'm definitely not a fan of (even though i like FP... though to be fair i haven't tried modern redux, and i've had to deal with a lot of awful redux code)

LWC is pretty decent structurally but theres all sorts of jank and undocumented stuff because of Salesforce™ haha. Its not terrible but working with something more generally used like react would be nice

Interesting! I usually did 2 and 5 but I think it definitely varies a lot based on what you have to make, and you have a lot more experience than I do in react. I probably should've done 6 more.

6 is great but admittedly easy to forget to do. 1 is annoying but stupid and easy which i like haha. i've been trying to avoid cleverness as much as possible these days.

the thing about 2 is that you can run into annoying things because objects have unique identities, so reacting to changes is harder since you have to go out of your way to compute that or look at the individual properties you care about. just one of the ways i dont love how react mixes with js's approach to identity and equality.