Most active commenters

    ←back to thread

    873 points belter | 11 comments | | HN request time: 1.151s | source | bottom
    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 #
    1. 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 #
    2. theryan ◴[] No.42952500[source]
    I'm glad I'm not alone in that sentiment. I haven't touched react since the move to hooks. People seem to like them though?
    replies(1): >>42997650 #
    3. ericyd ◴[] No.42952837[source]
    I only knew React until my current job, which uses Vue. I'd strongly recommend trying a framework other than React for your next project. After you're past the learning curve, it's much more intuitive.
    replies(2): >>42953599 #>>42960185 #
    4. Medicineguy ◴[] No.42953599[source]
    > I'd strongly recommend trying a framework other than React for your next project.

    This gave me a good chuckle (if you read it as next.js)

    5. 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.

    6. sesm ◴[] No.42954908[source]
    React's mental model has always been UI = F(data) and in ideal case any component is a pure function. But, of course, in most real apps there are cases when this mental model breaks: internal state, animations and side effects. The old way to provide escape hatches for those cases was to wrap a function into a class, where original function is 'render' method and the cases above are handled with lifecycle methods. The problem was that one piece of functionality often required updating several lifecycle methods, and for a big component that non-locality made things very hard. Hooks are a different way to express non-purity that keep code more local.
    replies(1): >>42954991 #
    7. kflgkans ◴[] No.42954991[source]
    Thanks, that makes sense. Interesting perspective on the UI = F(data), I did not know that. I still wish the mechanics were a bit more... intuitive... I guess? Personally, I'm a big fan of The Elm Architecture [1]. I felt that is a very nice way to separate state and logic. But I'm not such a big fan of Elm itself (subjectively).

    [1] https://guide.elm-lang.org/architecture/

    replies(1): >>42963929 #
    8. tobyhinloopen ◴[] No.42960185[source]
    I've tried many of them. They all suck.
    replies(1): >>42997633 #
    9. skydhash ◴[] No.42963929{3}[source]
    There was a great interview on ACM Queue [0] where they explain that paradigm. As a rule of thumb. Try to keep everything functional, and if you want to have state, keep it contained to its component.

    [0]: https://dl.acm.org/doi/10.1145/2984629.2994373

    10. veidelis ◴[] No.42997633{3}[source]
    Not a crazy take.

    Then try something like snabbdom or mithril.js.

    11. veidelis ◴[] No.42997650[source]
    No, not really. Some do, some don't. There are valid criticisms to dislike them. I'm on the side that thinks they are bad.