React Class Components V.S Functional Components Using Hooks (Part I: Deep Dive Into React Hooks Series)

Bashir
4 min readDec 14, 2020

--

If you look at an existing React application, you are almost guaranteed to see it written using class components combined with functional components. The main difference between a class and a functional component is the fact that class components can have lifecycle methods as well as a state (aka stateful components). We need to use a class component in order to use state and lifecycle methods because their logic is contained in the class React.Component which we have to inherit. Using a class-based component and inheriting from React.Component can have a few downsides because class-based components are:

  • bulky (they usually take more code to write and are slower to compile)
  • A challenge to test and debug (the logic of the various lifecycle methods can get confusing)
  • A bit tricky (you must be intimately familiar with the keyword “this”)

Because of the downsides mentioned above, React in 2018 introduced Hooks to replace class components. Hooks are simply away to use functional components with the added functionality of using lifecycle methods and states without the need for inheriting the class React.Component. You may be wondering about how we would use state in a functional component. Well wonder no more, as we can do use state in a functional component using the useState React hook.

useState( ) Hook

We can have a state in a class component as demonstrated in the code below:

In the code above, we can see that our Counter class is inheriting the class React.Component. This gives us the ability to set the initial state for a counter variable to zero (line 6). We can update/increment the state with each button click as shown on line 13. We use this.setState to update the state within this class. We can utilize the useState hook to convert this class component into a functional component as depicted below:

In order to use the useState hook, it has to be imported from react. Line 5 shows us how to initialize the state. Here, we are merely using array destructuring to initialize a state with a count variable to zero. The second destructuring variable, “setCount” is a function that will be used to update the state. If we have additional state variables, we can simply add them as follow:

If the variables are related, we can simply group them into an object as follow:

To access the count state above, we can simply do “state.count”. and to update the count state, we can write “setState({…state, count: newValue}). It is important to spread the state because the return value of setState will be the new state. If we only simply do setState({count: newValue}) then everything else in our state will be overridden (ie. height and length will be deleted).

useEffect( ) Hook

In class components, we had componentDidMount, componentDidUpdate, and componentWillUnmount. The functionalities of these lifecycle methods can all be handled by the single useEffect hook.

In the code above, the useEffect hook found in line 7 takes in a callback function which will run when the component gets mounted to the DOM, but we’ll also run for every rerender (when the state changes). This can be fine-tuned to only run when the component gets mounted only, but not for every rerender. This can be done by including an opening and closing bracket “[]” as a second argument to the useEffect hook such as follow:

The above code can be seen as similar to the class ComponentDidMount which will run only in the initial mounting of the component to the DOM, but will not rerun if the component gets rerendered. If we want useEffect to run only when certain state values change, then we can include those state variables in the empty array found in line 9 above.

To replicate the behavior of componentWillUnmount, which runs right before the component gets unmounted from the dom, we can have useEffect return a function. This returned function will only run when the component gets unmounted.

I hope this article will make converting React class components to React functional components with hooks a little easier.

--

--