Hacker News new | ask | show | jobs
by Rodeoclash 1403 days ago
As a long, long time user of React (from back in the days before they even had a decent state management system and we were using libraries like "MartyJS" to handle state) I do feel like React has lost its way a little bit for regular users.

What benefits are the hooks providing over class based components to the average user?. I understand Facebook probably has very unique requirements around performance but 99% of people using the framework probably don't suffer from these problems but have to put up with the downsides of the occasional weirdness that hooks introduce.

Example, the way you have to handle useCallback is something that bit me very recently. I had a parent component tracking deleted gallery items as a map of ids and a boolean indicating if the image had been deleted. For some reason I couldn't figure out why the deletion map was always stale in the callback. Sure I had a useCallback around it but I'd correctly added the state variable in the dependency array of the useCallback hook.

Well, it turns out I need to pass the deletion map down to the child <Image /> components of the gallery where the deletion was called from because they also had a useCallback in them. The child image components have to know about all the images that have been deleted so that the parent component has the correct up to date state. Crazy!

I get that it's Facebooks project and they can do what they want with it, but I have 6+ years sunk into using the framework now, it's a lot to throw away. That said, I have high hopes for the combination of LiveView and Web Component based libraries like https://shoelace.style/

3 comments

I would say the benefit of hooks and function based components is simplicity and ease-of-creation. Less boilerplate, less chance to mess up the life cycle of a component, especially for the vast majority of components that end up being pretty simple anyway.
I use hooks for animation, which requires setting up and tearing it down. I can do that with an easy hook, while if I had class based components, I'd have to keep track of every single time I want to use an animation, which is duplicated effort. Now multiply that by many different types of hooks, like querying for state, using a network connection (and not forgetting to close it down), etc.
Do you have a reduced code sample? I can’t quite picture the stale state issue.

(I suppose this is a good example in favour of the opposing “useCallback is premature optimisation” opinion)

This is the exact footgun I ran into yesterday:

https://codepen.io/rodeoclash/pen/poLqeYb?editors=1111

Even though `theState` is passed to the dependency array of the parent component which is tracking hidden images, it will still be stale!

After a while, I figured out that the child components, where the click originates from, also needed to have the map of deleted images passed to their dependency array. Total footgun.

For this specific example the problem is that the handleClick callback is using a stale/cached onImageDeleted callback (which indirectly has old state). If you add onImageDeleted to the handleClick dependency array, it beings to work as you expect.
Would the dependency linter catch this? I assume yes?
Yep, it will flag any references to variables in the outer scope that it doesn’t know for certain are stable.
Ahh, that's interesting.
Not on hand, but I'll put together one in a codepen now.