Comment by fud101
8 days ago
I'm tired of HN complaining about react for dumb reasons. To be clear, performance and bundle size matters for some things - if that's your complaint, whatever, i have no issue. My issue is there are whole host of use cases for which React is perfect, it has a functional declarative style which favours human understanding and correctness. This is a good thing. This is what the core of modern React gives you with functional components and hooks. You can do a lot with the core these days. Svelte and Vue are inferior for all the reasons React is functional and those other choices are imperative. I could go on but stop trying to make Svelte a thing, no one is buying.
I come from the native desktop/mobile world more so than from web, but I’d strongly contest the idea that declarative/functional is always better than imperative/OOP.
My experience is that declarative starts getting mind-bendy and awkward past a certain point of complexity. It’s nice when it’s simple enough for everything to fit on a single screen without too much scrolling, but past that you need to start breaking it out into separate files. That’s not too bad initially, but eventually you end up with an infinite-Matryoshka-doll setup which sucks to navigate for anybody who doesn’t know the codebase because they have to jump through 7 files to drill down to the code they’re actually interested in and makes it more difficult to get a thousand-foot view of it all.
Also, the larger the project the more likely it is that you’re going to have to pull off acrobatics to get the desired behavior due to the model not cleanly fitting a number of situations.
Declarative is solid for small-to-medium projects, but for more “serious” desktop class software with complex views and lots of panes and such I’d be reaching for an imperative framework every time. Those require more boilerplate and have their own pitfalls, but scale much better on average for a dev team with a little discipline and proper code hygiene.
I like functional code, but part of the issue with React in that regard is that it likes to hide state from you.
Eg all those providers that are inputs to your component but get hidden away.
It really diminishes the value proposition of functional code because the implicit inputs make the output feel non-deterministic. Eg you can have bugs because of state in a provider that is a transitive dependency of a downstream component. You never pass it through explicitly, so it’s not readily apparent that that state is important and needs to be tested.
I find imperative to be a mess because of bugs in teardown (eg someone added a div, that div isn’t properly removed when re-rendering, problems only appear when there’s 3 or more left over divs). Unless you tear everything down and rebuild it on view change, which sounds pretty functional to me (though probably not pure, but what is outside of Haskell?)
I could see where imperative might be more of a mess on the web compared to other platforms, but there’s probably ways to alleviate that. One that comes to mind is never using bare HTML primitives and only ever using components with proper teardown/management built in, of which could be enforced with some combo of linters and tests.
EDIT: Thinking about this some more, I suspect that intermingling of low level primitives and high level components is the root of a lot of problems on the web. It’s convenient in the moment but the mismatch in models is a recipe for trouble.
Alright, I'll bite. What about imperative programming fixes the scaling issues you're describing?
Typically programming scale is regarded as a benefit of FP over imperative programming, as the lack of mutable state results in less moving parts to reason about.
Part of it is solved by how longer files are much more readable in imperative setups and can benefit from things like an editor/IDE being more able to jump around within the file since it’s not a big tangled up deeply nested chunk and developers can add things like titled section dividers for the editor to latch onto.
And no language will fix all these woes on its own, but problems take a lot longer to crop up with a disciplined team in an imperative app compared with a declarative one.
FP probably does scale better when we’re talking about the nuts and bolts under the hood, but I don’t believe it’s well suited for UI except in the simplest of cases. There’s too much in that domain that’s at odds with the nature of a declarative/functional approach.
React is not actually functional - hooks are not functions, they're magic functions that smuggle state.
The main problem with react is that it's, ironically, not reactive. It greedily re-renders, whereas Vue actually reacts to state change.