Mimicking Lifecycle methods with Hooks in React

Patience Adajah
The Startup
Published in
3 min readJun 27, 2020

Starting out with React, I jumped in on writing functional components, I had some troubles using the useEffect hook, as I didn’t fully understand the component lifecycles.

I did a bit of biology and I enjoyed studying a lot about the lifecycles, especially the lifecycles of insects. How they progress from one stage to another until they finally become adults.

Just as it is in biology, I quickly realized that components in react also pass through a lifecycle. Components pass through different stages in their lifetime and possibly die at some point.

React components pass through three lifecycles: Mounting, Updating and Unmounting.

  • Mounting: here, it is simply putting elements in the DOM. At this stage, react has built in methods which are:
  1. constructor()
  2. getDerivedStateFromProps()
  3. render()
  4. componentDidMount()

At this stage, the render method will always be called in class components. The other methods will be called if you define them.

  • Updating: A component is updated, whenever there is a change in the component. This could be either via props or state. The react built in method for updated components are:
  1. getDerivedStateFromProps()
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate()
  5. componentDidUpdate()
  • Unmounting: A component is unmounted when it is removed from the DOM. There is just one built in method here, which is componentWillUnmount.

These component lifecycles are only available when writing class components. With functional components, some of these lifecycle methods are mimicked with react hooks. Mostly useState() and useEffect() hook.

constructor => useState()

Normally, in the constructor method, you set the initial values for state and bind the keyword “this” to refer to the current object in non-lifecycle methods. The constructor runs before the component is rendered.

In the above example, the Greeting component has three methods that run in the following order:

  • constructor() — sets the initial “greeting” state and binds the reference to “this” in the context of the setGreeting method.
  • render() — determines what content is displayed or “returned” by this component; initially only renders a button (with an event listener) and an empty paragraph (based on the empty string set for this.state.greeting in the constructor).

If a user clicks the button:

  • setGreeting() — updates the greeting state from an empty string to ‘Hello World!’, causing the component to re-render and triggering cliche alarms everywhere.
  • render() — runs again, now displaying “Hello World!” in place of the previous empty string.

Now to build the same component with functional components, we get this:

With “useState()”, it’s possible to simultaneously set an initial value for “greeting” and create the “setGreeting” function for updating the state in the future.

componentDidMount, componentDidUpdate and componentWillUnmount => useEffect()

Think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined. This method is triggered automatically after a component is successfully mounted and rendered for the first time. It is also useful when fetching data from an API.

The code above follows this pattern:

  • constructor/render — mounts and renders the component in an incomplete state (often with some sort of loading indicator)
  • componentDidMount — fetches data from an imaginary API and uses that data to update the component’s state, triggering the component to re-render
  • render — the component renders again, this time using the data fetched in componentDidMount to fully serve its intended purpose.

With useEffect() in functional components, the above code snippet is becomes:

Finally, I hope this helped you to understand how you can mimic lifecycle methods from class components in functional components with react hooks.

Resources

https://medium.com/swlh/react-lifecycle-hooks-71547ef4e7a8

--

--