Bootcamp
Search…
📅
Course Schedule
0: Language and Tooling Teaching Guide
1: Frontend Basics Teaching Guide
2: Backend Basics Teaching Guide
3: Backend Applications Teaching Guide
4: Backend Structure Teaching Guide
5: Full-Stack Applications Teaching Guide
6: Frontend Infrastructure Teaching Guide
7: React Teaching Guide
8: Advanced React Teaching Guide
9: Advanced Topics Teaching Guide
🧮
Algorithms Teaching Guide
💼
Interview Prep Teaching Guide
☺
User Experience Teaching Guide
8.5: Advanced useEffect
useEffect has a variety of specific uses. Usually they have to do with doing a thing once over the entire lifetime of a component or, doing something as an _effect _outside of the React app in response to a user action.

setTimeout

1
export default function App() {
2
​
3
useEffect(() => {
4
const timer = setTimeout(() => {
5
console.log('This will run after 1 second!')
6
}, 1000);
7
return () => clearTimeout(timer);
8
}, []);
9
​
10
return (
11
<div className="App">
12
<h1>Hello CodeSandbox</h1>
13
<h2>Start editing to see some magic happen!</h2>
14
</div>
15
);
16
}
Copied!

document.title

Set the title/tab text using React state. We only want to do this when the count state updates.
1
import './App.css';
2
​
3
import React, {useState, useEffect} from 'react';
4
​
5
export default function App() {
6
​
7
const [count, setCount] = useState(0);
8
​
9
useEffect(()=>{
10
document.title = `Count: ${count}`;
11
},[count]);
12
​
13
return (
14
<div className="App">
15
<h1>Hello CodeSandbox</h1>
16
<h2>Start editing to see some magic happen!</h2>
17
<h2>Count {count}</h2>
18
<p><button onClick={e => setCount(count+1)}>increment!!</button></p>
19
</div>
20
);
21
}
Copied!

window.innerWidth

Get a hold of the dimensions of the entire window (a property which is outside the direct control of the React App- it is not the child of the React root div).
Run this code and resize the window height to see the React state update.
We must use useEffect here because this property is not controlled inside of the React app.
1
import "./styles.css";
2
​
3
import React, {useState, useEffect} from 'react';
4
​
5
export default function App() {
6
​
7
// state that keeps the height number as state
8
const [height, setHeight] = useState(0);
9
​
10
// when App is created, set some listeners on the window
11
useEffect(() => {
12
​
13
// when the window resizes, set the state
14
const updateWindowDimensions = () => {
15
const newHeight = window.innerHeight;
16
setHeight(newHeight);
17
console.log("updating height");
18
};
19
​
20
// set the resize event listener
21
window.addEventListener("resize", updateWindowDimensions);
22
​
23
// when the component goes away, get rid of the listeners
24
return () => window.removeEventListener("resize", updateWindowDimensions)
25
​
26
}, []);
27
​
28
console.log("give height", height);
29
return (
30
<div className="App">
31
<h1>Hello CodeSandbox</h1>
32
<h2>Start editing to see some magic happen!</h2>
33
<h2>Height {height}</h2>
34
</div>
35
);
36
}
Copied!

Dynamically Settable setInterval

Use setInterval, but also be able to fully control the time delay between each interval using React state.
1
import "./styles.css";
2
​
3
import {useState, useEffect, useRef} from 'react';
4
​
5
function Counter() {
6
const [count, setCount] = useState(0);
7
const [delay, setDelay] = useState(1000);
8
​
9
// this value stays the same no matter
10
// how many times this function gets called / rendered
11
const savedCallback = useRef();
12
​
13
function callback() {
14
setCount(count + 1);
15
}
16
​
17
useEffect(() => {
18
// save the current value of count inside the above function
19
savedCallback.current = callback;
20
});
21
​
22
useEffect(() => {
23
// set the value of count (the updated value)
24
function tick() {
25
savedCallback.current();
26
}
27
​
28
// set the interval
29
let id = setInterval(tick, delay);
30
​
31
// clear the interval if delay updates
32
return () => clearInterval(id);
33
​
34
// when delay updates, call the effect
35
}, [delay]);
36
​
37
return (<>
38
<h1>{count}</h1>
39
<h2>Delay: {delay}</h2>
40
<p>
41
<button onClick={e=>setDelay(delay + 100)}>⬆️</button>
42
<button onClick={e=>setDelay(delay - 100)}>⬇️</button>
43
</p>
44
</>);
45
}
46
​
47
export default function App() {
48
return (
49
<div className="App">
50
<h1>Hello CodeSandbox</h1>
51
<Counter/>
52
</div>
53
);
54
}
Copied!
Original code + more examples found here: https://overreacted.io/making-setinterval-declarative-with-react-hooks/​

Further Reading

useRef

useRef allows React to keep track of a value between renders. We can see that we need to use it above to call the interval callback.
See more here:
Last modified 2mo ago