A hook that runs only after a component is mounted

A hook that runs after the component is mounted

10 mins



A hook that runs after the component is 'mounted'

Here is a hook that will will not run the supplied function on the first render:

import { useRef, useEffect, useState } from 'react'
const useDidMountEffect = (func, deps) => {
const isMounted = useRef(false)
useEffect(() => {
if (isMounted.current) func()
else isMounted.current = true
}, deps)
// reset on unmount; in React 18, components can mount again
// useEffect(() => {
// isMounted.current = false
// })

You can use it like this:

export default function UseMountEffectExample() {
const [toggle, setToggle] = useState(false)
useEffect(() => {
console.log('Running useEffect. Toggle Value: ', toggle)
}, [toggle])
useDidMountEffect(() => {
// react please run me if 'key' changes, but not on initial render
console.log('Running useDidMountEffect. Toggle Value: ', toggle)
}, [toggle])
return (
<div className="flex flex-col content-between">
<button onClick={() => setToggle((prev) => !prev)}>Toggle</button>
<p>Toggle: {toggle ? 'true' : 'false'}</p>

Codepen here to play round with: https://codepen.io/rainkinz/pen/ZEMYaeN

Some notes on useEffect

useEffect by default runs after the first render and after every update. React runs useEffect after it has finished updating the DOM on render.

useEffect(() => {
// do something when the component renders
return () => {
// cleanup

In certain cases, applying the effect after every render might not be desirable. We can list arguments that will cause useEffect to fire if they have changed:

useEffect(() => {
// do something when the component renders but only if count has changed
}, [count])

The same thing was done in class components using prevProps or prevState in componentDidUpdate remembering that the componentDidUpdate lifecycle method is invoked during each render, except the first one. The componentDidMount is only invoked once, after the first render.

componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
// do something when the component renders

Note that listing no arguments in the dependency array [] makes the effect and cleanup run only once, on mount and unmount.

useEffect(() => {
// do something when the component mounts
return () => {
// cleanup on unmount
}, [])