React: Class Component VS Function Component with Hooks

danielleye

Danielle Ye

Posted on January 3, 2020

React: Class Component VS Function Component with Hooks

Class Component

Before React Hooks, when we want to create a dynamic component, we have to create a class component and use lifecycle methods to change states to make it reusable and encapsulate.

By creating an ES6 class, the class needs to extend React.Component with a render method in it, which will return the JSX markups. Also, we need to assign the initial state in the constructor with this.state. As an example, here we create a simple clock component with class. To make the clock working, we have to add Lifecycle Methods to our Class. We put elements into the DOM, it is called mounting in React. Same, We remove elements from the DOM, it is called unmounting. In React, mounting a component will invoke the following four build-in methods:

  • constructor()
  • getDerivedStateFromProps()
  • render()
  • componentDidMount()

More information please read from React Doc: Commonly used lifecycle methods

In our example, we set the initial state in the constructor and defined componentDidMount() to set the time every second. So the clock will update the state every second with the current time.

class ClockUsingClass extends React.Component {
    constructor(props) {
        super(props)
        this.state = { date: new Date() }
    }

    componentDidMount() {
        this.time = setInterval(() => {
            this.changeTime()
        }, 1000)
    }

    componentWillUnmount() {
        clearInterval(this.time)
    }

    changeTime() {
        this.setState({ date: new Date() })
    }

    render() {
        return (
            <div className="clock">
                <h1>Hello! This is a class component clock.</h1>
                <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
            </div>
        )
    }
}

Obviously we can see, for a class-based component, we need several steps to make it work with state-changing:

  1. Create a class with constructor(props) and render() methods.
  2. Set initial state with this.state statement in the constructor.
  3. Use this.setState() to update states.
  4. Use lifecycle methods like componentDidMount(), componentWillUnmount(), componentDidUpdate() etc. to change states

Function Component with hooks

Hooks are a new addition in React 16.8. The most useful feature of Hooks is that it allows using state without using class.

There are two most commonly used hooks: the state hook -- useState and the effect hook -- useEffect.

State hook allows you to add states in the function component. Instead of setting an initial state with this.state statement in the constructor, we can import { useState } from react, which will allow you to set the initial state as an argument. State hook will return a pair of values: the current state and a function that updates it. Usually, we will use useState like this:

    const [time, setTime] = useState(new Date())

Effect hook will get invoked with the first DOM updating. We can pass in a function in useEffect, and every time the DOM gets updated, the function in useEffect will get invoked too. Also, the effect hook allows you to pass in an array as the second argument, which contains all the dependencies that will trigger the effect hook. if any of the dependencies changed, the effect hook will run again. This feature provides us a more efficient way to make an Ajax request. Instead of making the request every time with DOM updates, you can pass in dependencies that only make the request while these values change.
useEffect can be used like:

    useEffect(() => {
        setInterval(() => {
            changeTime()
        }, 1000)
    })

So, here we re-write the clock we created above with hooks

const ClockUsingHooks = props => {
    const [time, setTime] = useState(new Date())

    const changeTime = () => {
        setTime(new Date())
    }

    useEffect(() => {
        const tick = setInterval(() => {
            changeTime()
        }, 1000)
        return () => clearInterval(tick)
    })
    return (
        <div className="clock">
            <h1>Hello! This is a function component clock.</h1>
            <h2>It is {time.toLocaleTimeString()}.</h2>
        </div>
    )
}

Summary

Comparing with these two ways to create a component, we can clearly see that hooks need less code and it is more clear to read and understand. Hooks give us a more efficient way to replace lifecycle methods.

Check out the repo to make a simple clock here

💖 💪 🙅 🚩
danielleye
Danielle Ye

Posted on January 3, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related