Understanding React's useEffect()
The primary reason to use an Effect is to synchronize data with an external system.
Per the React docs, "If you’re not trying to synchronize with some external system, you probably don't need an effect."
useEffect
takes two arguments:
A setup function
The logic inside of the setup function will run every time a change occurs in a dependency
A cleanup function may optionally be returned from inside the setup function which will execute every time the component un-mounts.
Optionally, the dependencies, specified in an array
If no dependencies are specified, the setup function will run on every re-render.
If an empty array is specified as a dependency, the setup function will run only on the initial rendering of the component.
In the example below, every time the todos
array is modified, useEffect
synchronizes todos
with a TODOS
item in local storage. We know that this is the case because todos
are specified in the dependencies array, which can be seen as the last argument in the useEffect
call. As an unhelpful example of a cleanup function, useEffect
in this example will call console.log('cleanup')
whenever the component un-mounts prior to a re-render.
import { useEffect, useState } from 'react'
function App() {
const [todos, setTodos] = useState(() => {
return JSON.parse(localStorage.getItem('todos')) || []
})
useEffect(() => {
localStorage.setItem('TODOS', JSON.stringify(todos))
return () => console.log('cleanup')
}, [todos])
}