Side-effects
For side-effects other than simply changing the application state we'll be using the useEffect hook. There's three parts to each useEffect hook: setup, cleanup, and dependencieswhere cleanup and dependenciesare optional.
1
useEffect(
2
() => {
3
// body of a setup function
4
return () => {} // cleanup function
5
},
6
[] // dependency array
7
)
Copied!

Setup

The setup is where all the hook's logic is placed.
1
useEffect(() => {
2
console.log("setup")
3
window.addEventListener("mousemove", (event: MouseEvent) => {
4
setPosition({ x: event.clientX, y: event.clientY })
5
})
6
})
Copied!
Hook written like that will run on each render, and create a myriad of event listeners.
In fact this code will break your browser.

Cleanup

The setup can return a function that will be called when its time to "undo" the changes the hook has made.
1
useEffect(() => {
2
console.log("setup")
3
const handler = (event: MouseEvent) => {
4
setPosition({ x: event.clientX, y: event.clientY })
5
}
6
7
window.addEventListener("mousemove", handler)
8
9
return () => {
10
console.log("cleanup")
11
window.removeEventListener("mousemove", handler)
12
}
13
})
Copied!
In fact this code will probably break your browser.

Dependencies

We really only want the hook to run once:
1
useEffect(() => {
2
console.log("setup")
3
const handler = (event: MouseEvent) => {
4
setPosition({ x: event.clientX, y: event.clientY })
5
}
6
7
window.addEventListener("mousemove", handler)
8
9
return () => {
10
console.log("cleanup")
11
window.removeEventListener("mousemove", handler)
12
}
13
}, [])
Copied!
Second argument to the useEffect function is the array of dependencies. Hook behavior changes depending what's in it:
  • null or undefined: the hook will run for every render
  • [] (empty array): the hook will run once, after the first render
  • [value1, value2]: the hook will only run when one of the values changes

Resources