Joy of React (by Josh Comeau)
typescript
Table of Contents
Just jotting down some quick notes and learnings from the course by Josh Comeau.

Rendering v.s. Painting
The difference:
- A re-render is when React checks if anything needs to change on the screen.
- A repaint happens when the browser actually updates what you see.
For example:
function AgeLimit({ age }) {
if (age < 18) {
return <p>You're not old enough!</p>;
}
return <p>Hello, adult!</p>;
}
- If you change
agefrom 16 to 17, React re-renders, but since the output is the same, nothing changes in the DOM. - If you change
ageto 18, React sees a difference and updates the DOM.
Unique keys
Given this code:
const stickers = []
stickers.push({
x: event.clientX,
y: event.clientY,
})
{stickers.map((sticker) => {
<img ...>
})}
Do not do this:
{stickers.map((sticker, index) => {
<img key={`sticker-${index}`} ...>
})}
- Issue: Work in some case, but NOT in every case.
- This removes the warning but isn’t safe if stickers are added, removed, or reordered. If we remove the first item in the array, React will actually delete the DOM nodes associated with the last item in the array, and will then have to do a bunch of work on all the other DOM nodes.

Slightly better:
{stickers.map((sticker, index) => {
<img key={sticker.src} ...>
})}
- This is okay ONLY if we know and can guarantee that
srcis unique
Ideally, do this:
stickers.push({
x: event.clientX,
y: event.clientY,
id: crypto.randomUUID(),
})
{stickers.map((sticker) => {
<img key={sticker.id} ...>
})}
- Unlike
Math.random()(changes every render) or index keys (shift when array changes), - Stable IDs let React only add new elements and leave existing ones untouched -> minimizing expensive DOM operations and avoiding mismatched reuse.
But there’s limitations:
- We may not be able to assign unique IDs at creation
- However, we can store temporary ID in memory as it is still cheaper than generating it for every item in every render
const [stickersWithKeys, setStickersWithKeys] = useState( stickers.map(s => ({ ...s, key: crypto.randomUUID() })) )
Hooks
useId
- Each instance of this component will receive a different value -> Multiple instances of the component can exist compared to if we hardcode
id - Produces the same value across server and client renders
function LoginForm() {
const id = React.useId();
return <Something id={id}>
}
useRef
Why:
- Accessing DOM elements directly
const videoRef = useRef()
// assigning it
<video ref={videoRef}>
// accessing it
videoRef.current.playbackRate = 2
- Storing value without causing a re-render
const countRef = useRef(0);
const increment = () => {
countRef.current += 1; // doesn't trigger render
console.log(countRef.current);
};
useEffect
Event subscriptions
Instead of:
<div
className="wrapper"
onMouseMove={(event) => {
setMousePosition({
x: event.clientX,
y: event.clientY,
});
}}
/>
Do this:
// Avoids recreating the event listener on every render
React.useEffect(() => {
function handleMouseMove(event) {
setMousePosition({
x: event.clientX,
y: event.clientY,
});
}
window.addEventListener('mousemove', handleMouseMove);
}, []);
<div className="wrapper" />