I've completely stopped using class components after spending some time with Hooks in a small-to-mid-sized application.
The big wins for me were:
- passing an empty array as the last argument of useEffect makes useEffect work in a similar fashion to the old ComponentDidMount. You can have any number of useEffect invocations in a component, and for a component that is, say, loading data from two different sources, I find having two discrete useEffects loading just what they need much more clean/intentional than putting everything into a single lifecycle method.
- using Hooks with Context almost completely fills the giant state management hole that has been (imo) hampering React since its inception. Hooks + Context is a cleaner and more comprehensible solution than React + Redux for any application that has a reasonable amount of state complexity. For data-heavy applications, Redux may still be a good choice, but for everything else, the Hooks + Context combination is hard to beat.
How do you handle the drawback that changing the context will rerender all components that use the context? Putting too much state into a single context does seem like it could cause performance issues, especially with state that changes often.
I agree that if you had a large (in the dozens, if not hundreds) number of dependent components, it could be an issue. However, I've noticed no performance degradation with my usage -- I use a top-level AuthContext component to handle user data/login state, and another for access/caching of the app's main data.
In a single view (for lack of a better term), I'd guess the largest number of components that access either context is six.
Can you elaborate a bit about Context? I've been curious but wrapping multiple context layers to get multiple values feels awkward and wrapping an object to get CD around that feels like it screws over React rerendering logic.
Sure. The app I'd been working on had previously been using the original 'render prop' style of accessing context in functional components and using the this.contextType accessor for class-based components. Both approaches had their downsides:
- 'render props' are fairly awkward to write, and add a lot of noise to a component that's working with data from multiple contexts.
- this.contextType can only give a component access to one context. This is a pretty big problem.
With Hooks, useContext lets you reference and destructure contexts in a really elegant way. Say you want to show a user's name if they're logged in, with the render prop approach it's something like:
The big wins for me were:
- passing an empty array as the last argument of useEffect makes useEffect work in a similar fashion to the old ComponentDidMount. You can have any number of useEffect invocations in a component, and for a component that is, say, loading data from two different sources, I find having two discrete useEffects loading just what they need much more clean/intentional than putting everything into a single lifecycle method.
- using Hooks with Context almost completely fills the giant state management hole that has been (imo) hampering React since its inception. Hooks + Context is a cleaner and more comprehensible solution than React + Redux for any application that has a reasonable amount of state complexity. For data-heavy applications, Redux may still be a good choice, but for everything else, the Hooks + Context combination is hard to beat.