Since the arrival of React v16.6.0 in October of 2018, some new and exciting features have created the potential for React developers to choose differently between the use of Functional and Class Components. Up until this point, the natural choice between the two would typically hinge upon whether there was a need to access state within the component, or perhaps if there was a need to use PureComponent to refrain from unnecessary re-rendering to the DOM. If either of these was deemed to be required, then the choice would be for a Class Component over a Functional Component. This would be despite the fact that Functional Components are typically easier to read and test (I recommend Kent C. Dodds’ react-testing-library).
However, since the release of 16.6.0, the need to write a Class Component instead of a Functional Component is no longer so clear-cut. A set of new features, such as React.memo() and Hooks, has created the potential to significantly alter how developers approach writing React Components.
In the case of React.memo(), this new feature has enabled us to save ourselves from unnecessary costs on performance, by creating the ability to wrap a Functional Component inside of a Higher Order Component (React.memo()), thus ensuring that the particular component will only re-render if the props that are passed to the component have changed. (Typically, all components are re-rendered to the DOM after a change.) Whilst PureComponent creates similar advantages through use of the
shouldComponentUpdate() method, this must be used within a Class Component. React.memo() allows the developer to by-pass the need for a Class Component in some circumstances.
Whilst React.memo() created this new potential to alter certain key decisions for the developer, Hooks have taken it much further again. With their release in React v16.8 in early February 2019, one of the main reasons why a developer would choose a Class Component over a Functional Component has suddenly been challenged quite heavily. One of React’s key attractions is how it manages state. As state changes, data is managed and components re-render incredibly seamlessly and rapidly. Up until now, the use of state inside of a component would require the use of a Class Component. Thus, in a large React application, it is often the case that the vast majority of components are Class Components.
The introduction of Hooks has created the potential to change this approach in one fell swoop. Hooks allow Functional Components to access state. Indeed, they do not work with Class Components and must be used only with Functional Components. By importing
useState to your Functional Component, state can change and the component can be re-rendered without the use of
setState(). What’s more, state does not have to be represented as an object, and can take the form of other types such as strings or numbers. Another important feature that comes as part of Hooks are Effects. Effects can replicate the benefits of React Lifecycle Methods inside of a Functional Component, but with less (or indeed no) duplication of code. With the release of this hugely significant new feature, the use of Class Components in React applications may well be greatly reduced over time.
There appears to be a pattern of setting aside the use, and in fact need, for Class Components in React. The official documentation has recently described classes as confusing, as a barrier to learning React, as a struggle, and as a cause for disagreement amongst experienced React developers. Whilst it claims that there are no current plans to remove classes from React (crucially, there are no breaking changes with the introduction of Hooks) and that Class Components may continue to be used alongside Functional Components, the question must indeed be raised about the future of Class Components in React. If their need becomes obsolete over time, the natural conclusion would be that Functional Components will become the de facto standard component type in React.
This will be worth considering for any future development of React applications post 16.8. Whilst there is no current need for refactoring of existing applications (again, Class Components are not being removed or even actively discouraged), the decision process for choosing component types should be approached very differently.