Some time ago React got a new major feature called hooks. They are a way to add state to component functions. Things that required lifecycle methods and in turn, component classes now can be achieved with a component function that calls hook functions.
This fact on its own is already a huge boon. We write our first UI draft with component functions and then don't have to restructure anything, drop in our hooks, and be done with it.
It also eliminates deep component trees. Things that had to be done with higher-order components and render props, which were design patterns constructed with component classes and their lifecycle methods. Auth, UI state, services, internationalization, etc. everything was a component nested in a component.
Hooks add another dimension for nesting. This new dimension allows decoupling the nesting of the visible UI components from the nesting of the invisible behavior of our applications.
But I think these points aren't the main selling point of hooks.
What makes them powerful is that they offer a different way to think about the component lifecycle.
Before hooks, we would think in terms of lifecycle events.
Do I need my component to do something when its rendered for the first time? Let's put the code in
Will the component be removed? Put it into
For updates? Put it in
getDerivedStatesFromProps... or ... well now it gets a bit complicated...
Hooks remove this problem once and for all.
With hooks, the focus is moved from the different lifecycle events we want to hook into to the actual state we want to observe.
We create the state we need to observe with
useState and use it with
useEffect to trigger code when it changes.
The only things we care for are the state changes and if our component gets removed from the DOM.
When we used lifecycle methods, it wasn't enough to know what we want to observe, we also needed to know where at the lifecycle it could occur. This extra step could lead to UI bugs.
For example, React would re-use a component that was already rendered, change the props and
componentDidMount wouldn't be called again. The
useEffect hook would recognize the changed props and rerun its code.
This sounds like a pretty dull change in thinking about component behavior, but I think it's a brilliant one that eases the creation of component-based UIs tremendously.