←back to thread

873 points belter | 1 comments | | HN request time: 0.749s | source
Show context
dtquad ◴[] No.42948592[source]
>Frontend development is a nightmare world of Kafkaesque awfulness I no longer enjoy

As a backend/systems engineer I recently had to look at a React + Typescript + MobX app from 2019/2020. It is true that that some things, especially the webpack config and Typescript loading, were outdated but the overall design and architecture of the app was still understandable and modern. With some help from ChatGPT it took very little time to migrate to Vite and update dependencies. By 2019/2020 React Hooks had already been out for some time but there were still some class components in the app. They were easily migrated to functional components + Hooks using ChatGPT.

replies(9): >>42948755 #>>42949267 #>>42949480 #>>42949689 #>>42951645 #>>42952358 #>>42953864 #>>42954167 #>>42960182 #
kflgkans ◴[] No.42952358[source]
If there is anyone here who has time to explain to me (or link articles about) why functional components and hooks are considered to be better than class components, please enlighten me.

Up until roughly 4-5 years ago I was doing small front-end React apps on the side (I'm a backend engineer) and was feeling very productive with class components. They made sense to me, concerns were nicely separated, and I felt I could reason pretty well about what was called when and how state was manipulated.

Then hooks came around, I tried them a few times, but I just felt so lost. Suddenly everything is intermingled in one function and we're using side effects to react to changes and manipulate state. I could no longer understand when which code was executed, and especially following and manipulating state became impossible for me.

The projects I already, I kept with class components. Haven't done any new front-end projects since then.

replies(4): >>42952500 #>>42952837 #>>42953730 #>>42954908 #
1. rimunroe ◴[] No.42953730[source]
> If there is anyone here who has time to explain to me (or link articles about) why functional components and hooks are considered to be better than class components, please enlighten me.

Static evaluation of which instance properties are being used in a class instance is much harder than evaluating which variables are being referenced in a function. There's no need to worry about calling context or binding instance methods. Functions minify much better because you don't have to worry about preserving long property names like componentDidUpdate. With class components, sharing logic involving state between components required either functions taking a state setter and whatever slice of state you needed, or--more commonly--higher order components. With function components and hooks, the code responsible for initializing and updating state isn't tied to an instance. Now you can share that code with a plain function without needing to pass an entire slice of state and an update function into it. Instead of needing to shove all your update-related code into the same componentDidUpdate or componentWillUnmount methods, you now split them into different calls to useEffect.

> Suddenly everything is intermingled in one function and we're using side effects to react to changes and manipulate state. I could no longer understand when which code was executed, and especially following and manipulating state became impossible for me.

If you're talking about using useEffect to respond to changes by setting state: that's almost always a code smell and sounds like trying to sync state with props. This was an anti-pattern long before hooks, and was called out explicitly in the docs.

Having worked on a lot of class components and function components, class components offer a lot more opportunities for bugs which can't be statically prevented. On the other hand, most of these bugs can be caught in function components and hooks by a linter, or are just prevented entirely by the design. A frequent question which came up during the class component era was what code belonged in the class's constructor, componentWillMount, or componentDidMount methods. This always came with caveats, because generally component initialization isn't something developers should be thinking about because it can happen many times before anything appears on screen. Function components offer fewer opportunities for this. The useEffect hook forces people to think purely in terms of running effects in response to changes in variables which have been closed over, and about what things need to be done to clean up after the effect has run. Responding to user events (e.g. onClick) is almost exactly the same as it's always been other than cosmetic changes.

I'm not sure how everything being in a single function offers worse organization than everything being within a class. Instead of instance properties you have variables. Instead of methods you have inner functions.