For example a flurry of setStates could be wrapped up in one single state. If it gets too complex - into a reducer.
Components that don’t benefit much from splitting up could have their business logic wrapped into a context, and let the view code be just jsx without all the interweaving of code and templates.
Maybe the one benefit of classes was like it forced you to think in business logic, then render. React still has that, you just need to dive a bit deeper into its toolbox.
The result usually turns out much more flexible - contexts neatly wrap business logic for all of its descendants, classes don’t.
I think this was maybe because react actually allows you to write messy code, and it’s still performant and works. But in the end it just kinda postpones the inevitable maintenance burden.
I guess solid.js from the looks of it might postpone it a bit more. I just worry that solid looks more like magic, and some invariant somewhere will just break and I wouldn’t know what sequence of reactions actually led to that infinite loop that crashed the page. Haven’t tried it myself though, might more understandable in the end…
You've just deoptimized your app, and your whole component will re-render on every change.
> Components that don’t benefit much from splitting up could have their business logic wrapped into a context
You did it again. More unnecessary re-renders.
> it’s still performant and works
True that 'it works', but it's usually not as performant as you think - we just have really fast computers and phones now.
There's a parallel here to "no, you did not find a bug in the compiler". Yes, ok, once every five years or so I actually did find a bug in the compiler, but assuming you aren't that smart is still a far far better default approach.
On top of that, profiling and optimizing a real world application with a dozen hooks in every component is pretty painful.
If you have 3 useState each of those will use 3 useReducer internally (every hook is implemented on top of useReducer), If you consolidate them into one useReducer then you will end up with the same thing performance wise. Maybe even better. Whenever an event is pushed into the hook's queue it marks the component as dirty. The next call to useReducer will then reduce all unprocessed events into the current state. It's entirely possible that having less hooks and therefore less metadata in the background can improve performance more than avoiding the theoretical cost of rerendering a component that most likely would have to be rerendered anyway.
But you certainly are correct that useState is reducer based. I'm pretty sure one is only avoiding rerender via using multiple `useState` if they don't implement the reducer in a way where it returns the original object when there was no net change. If you are able to implement the such that it only returns a new object when there really is a change, then a single useReducer call is strictly more efficient than multiple useStates. (This might require more complicated code, as returning a new object every time is often the easy way to implement reducers.)
It’s understandable to stumble into this difficulty though, and a bit of deceptive marketing on the part of the hooks folks. They should be upfront that using hooks well in a real app requires a lot of careful thinking of the kind that many “typical” programmers do not have much practice in, and then the maintenance of whatever code comes from the effort. The functional-programming-mindshare situation seems to be improving slowly, but still.
If the lifecycle methods you're referring to are things like componentWillReceiveProps or getDerivedStateFromProps then the React blog covers why they were problematic https://reactjs.org/blog/2018/06/07/you-probably-dont-need-d.... It was very common for developers to make things that would repeatedly rerender when other parts of their app updated. Hooks make that far less likely to happen.
That said, I agree that a getDerivedStateFromProps method is more readable and much clearer than useEffect(()=>{ // stuff }, [big, list, of, props]);
when, as I often encounter, organizations mandate all hooks all the time they are not throwing the baby out with the bathwater, but they are maybe throwing out the baby's rubber duckie without considering that might be useful to have around at times.