Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've not used any Svelte significantly yet, so your points may stand.

I have, however, written React for years. If anything in Svelte is more confusing to juniors than how useEffect works, especially in conjunction with unstable references, I would be literally amazed.

useEffect is a loaded automatic pointed at your face if you don't fully understand it. It is truly a terrible API due to how intimately you have to understand JavaScript for it to always work properly.

I can't imagine anything worse in Svelte. If there is, I'd love to hear it.



Agree 100%. The migration from componentDidMount, componentDidUpdate, etc to useEffect was a major regression in terms of readability.

The return function in useEffect vs. componentWillUnmount is just terrible. This is always a bizarre topic for juniors.


I actually think that useEffect is an amazing abstraction. It lets you group related functionality like subscribing and unsubscribing into one place and makes it very difficult to leak stuff or use stale values.

I didn’t write many class components beforehand though, so my mental model didn’t have to change all that much.


I wrote a lot of class components and getting used to effects was a 2-week-long headache for me. But then it clicked and I can't go back ever again. Hooks are really nice abstraction. However, sometimes I would like people to name their effects: `useEffect(function clickHandler() {})`, but I understand it looks ugly.


I don't disagree that useEffect is a great extraction overall. But the mental load to understand it vs. explicit lifecycle methods is significantly worse.

The ability to subscribe is indeed amazing (this was much more verbose in class components).


Same experience, I've started working with React when Hooks were introduced in a greenfield project. My last experience with JavaScript was jQuery and Angular 1. I was blown away by the functional-declarative approach of React Hooks, I can't believe that people haven't used it before.


agreed. transition from classes to hooks and useEffect was confusing at first but it now seems very predictable and sensible (does get a little hairy when you have one effect dependent on another).

just started writing my own named effects (eg useAuth() for encapsulating firebase auth) and still in a bit of an uncanny valley with doing that - but again it's very logical once you get used to it and actually in the end a simpler mental model of component state.

never want to go back.

junior devs, start with useState, it'll all flow from there.


As someone familiar with the old react API, I agree 100% about useEffect being super arcane.

There's just too much magic going on, which is the same thing that makes me reluctant to write Vue or Svelte (after reading this)


If you use `<script setup>` in Vue, yeah it's some compiler magic similar to Svelte, but otherwise that's not really the case, for example Vue tracks depdendencies using ES6 Proxy, which is just a language feature.


I agree, but it can be made easier by exposing named functions that help like useUnmount

https://github.com/streamich/react-use/blob/master/src/useUn...


Why do you think it's terrible?


Nothing about its usage implies what it actually does. It's about API affordances. You can't simply just read the code as someone inexperienced with React and say "oh, I know what this does". Returning a closure as the result of another closure has no inherent meaning as to when that closure would be called, because there's no "name" for that functionality.

And don't even get me started about the dependencies array, which has different behaviour whether you omit the argument, or pass an empty array, or pass actual `useState` dependencies, or pass other unrelated variables. Again, it's something you just "need to memorize" to use React.


If I hadn't been using React for many years before they introduced useEffect and various other hooks, they would have all been incredibly confusing. They still are really confusing when used in "clever" ways, especially with developers being allergic to writing comments. Even something as simple as `// this will do X when the component unmounts` make reading usages of useEffect 10x easier (vs. having to remember what happens when you return a function)

Sometimes I do miss the simplicity of componentDidMount... I guess you can always still write class-based components. Too bad they're not in vogue anymore! Feels like every library is hooks-based these days.


Totally agree re comments. They're necessary. Hooks do have huge advantages for composability and flexibility, and that can't be denied. But the API is just so arcane.

If my company wasn't a React shop, I'd probably be using Vue. I used Vue at my previous company and liked it a lot.

Headless libraries like `react-table` that use hooks are a revelation though. So nice to get pretty much all the behaviour you could ever need, without it making UI decisions for you. Difficult to use at first and wrap your head around, but hoo boy is it great to have the power to fully control the rendering!


It's very easy to convert a hook to a HoC, purely wrapping that functionality in a class component.


Also true. It just seems like `class` has become a bit of a dirty word, at least the last two places that I've worked on React codebases.


I agree it has. I think this is because hooks have been talked about by facebook as the future of react. There seems to be no appetite for class based react improvements in the future. No wonder people move to the thing that will be better supported, regardless what it is.


Overloading the meaning of native language features is not the most beginner friendly. It’s a quirk you just have to remember.

Compared to an explicit method name it is much less intuitive.


useEffect makes easy things easy and hard things very hard indeed.

After building a few non trivial apps in React with hooks I'm convinced that what you really need for that model to work smoothly is a new language that tracks things like hook dependencies for you.


Eslint will ensure all dependencies are listed in the array. Is there something more you’re wishing for?


The ESLint plugin helps. But it depends on static analysis. And static analysis is fundamentally incapable of taking advantage of any information only available (or more easily accessible) at runtime.

One limitation that pops up fairly frequently in my experience: Only React's first party hooks can get exceptional treatment by the plugin, i.e. the setState function returned from useState can be assumed to never change and omitted from dependency lists, because those cases are hard coded into the static analysis. There's no way for custom/third-party hooks to indicate to the plugin that the thing they return will never change in the same manner, even if all they're doing is passing through a setState function directly from a useState call that will very obviously also never change reference, for instance.

They can probably offer some rudimentary support for this use case with static analysis by offering some kind of exceptions API for the user to spell out the names of the hooks and return values that should get this preferential treatment, like they have with the additionalHooks config option [1], but the DX around integration with third party modules is going to remain a messy unsolved problem.

Language/runtime level support for this pattern would hopefully be flexible enough to know that the thing we returned from our custom hook or third-party hook is fundamentally the same thing as (or shares some runtime property with) the setState returned from a useState hook, and treat it the same way, regardless of what our hook is called or how it's implemented or where it's from.

Unfortunately it sounds like the React team is planning to double down on static analysis to improve hook DX, so this doesn't seem to be an area they'd be likely to invest in. I think that's a shame because static analysis is much more difficult for users to extend and experiment with new paradigms for than runtime abstractions, and will start to stifle innovation in the ecosystem as we come to rely on it for more and more heavy lifting.

[1] Which, by the way, stops working as soon as you deviate even a tiny bit from the assumptions made in the static analysis, in ways that would be completely trivial to infer as functionally identical for any runtime system. The only way to address these shortcomings is to send in a PR to make the static analysis make fewer assumptions (unlike a runtime system which you can usually extend through some clever wrapping if it's just a function), for which YMMV: https://github.com/facebook/react/pull/20051


I agree with all of this except your terminology: static analysis of javascript can't solve this problem because of the limitations of the language semantics. Static analysis in general could, I think. It just might require a different language with different semantics.


mobx tracks dependencies for you, and it's not magic if you understand the basic concepts of proxies and dereference


MobX does that.


Yeah useEffects was the start over overcomplicating react.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: