Skip to content

Commit 3d3c2c7

Browse files
chantastickentcdodds
authored andcommitted
migrate: exercise 05 to kcd-workshop format
1 parent 02c5aad commit 3d3c2c7

File tree

13 files changed

+96
-112
lines changed

13 files changed

+96
-112
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# DOM Side-Effects
2+
3+
For this extra credit we're going to auto-focus on the username input if there's
4+
an error after submitting. This is a common practice for accessibility purposes
5+
(to focus on the first input that has an error after a form submission).
6+
7+
So for this exercise you're going to use `useRef`. The example above should be
8+
enough to get you working. You'll pass the ref you create to the input and then
9+
in a `useEffect` you'll call `.focus()` on the input element whenever the error
10+
is displayed.
11+

src/exercise/05.tsx renamed to exercises/05.dom-side-effects/01.problem/index.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
// DOM Side-Effects
2-
// http://localhost:3000/isolated/final/02.extra-4.tsx
3-
41
import * as React from 'react'
5-
import {useLocalStorageState} from '../utils'
2+
import * as ReactDOM from 'react-dom/client'
3+
import {useLocalStorageState} from '~/shared/utils'
64

75
function UsernameForm({
86
initialUsername = '',
@@ -100,4 +98,6 @@ function App() {
10098
)
10199
}
102100

103-
export {App}
101+
const rootEl = document.createElement('div')
102+
document.body.append(rootEl)
103+
ReactDOM.createRoot(rootEl).render(<App />)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# DOM Side-Effects

src/final/05.tsx renamed to exercises/05.dom-side-effects/01.solution/index.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
// DOM Side-Effects
2-
// http://localhost:3000/isolated/final/02.extra-4.tsx
3-
41
import * as React from 'react'
5-
import {useLocalStorageState} from '../utils'
2+
import * as ReactDOM from 'react-dom/client'
3+
import {useLocalStorageState} from '~/shared/utils'
64

75
function UsernameForm({
86
initialUsername = '',
@@ -92,4 +90,6 @@ function App() {
9290
)
9391
}
9492

95-
export {App}
93+
const rootEl = document.createElement('div')
94+
document.body.append(rootEl)
95+
ReactDOM.createRoot(rootEl).render(<App />)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Side-Effect Cleanup
2+
3+
In this extra credit we're going to use a completely different example. We're
4+
going to make a `<Tilt />` component that renders a div and uses the
5+
`vanilla-tilt` library to make it super fancy.
6+
7+
The thing is, `vanilla-tilt` works directly with DOM nodes to setup event
8+
handlers and stuff, so we need access to the DOM node. But because we're not the
9+
one calling `document.createElement` (React does) we need React to give it to
10+
us.
11+
12+
So in this exercise we're going to use a `ref` so React can give us the DOM node
13+
and then we can pass that on to `vanilla-tilt`.
14+
15+
Additionally, we'll need to clean up after ourselves if this component is
16+
unmounted. Otherwise we'll have event handlers dangling around on DOM nodes that
17+
are no longer in the document which can cause a memory leak.
18+
19+
To be clear about the memory leak, just imagine what would happen if we mount a
20+
tilt element, then unmount it (without cleaning up). Those DOM nodes hang around
21+
because the event listeners are still listening to events on them (even though
22+
they're no longer in the document). Then let's say we mount a new one and
23+
unmount that again. Now we have two sets of DOM nodes that are still in memory,
24+
but not being used. We keep doing this over and over again and eventually our
25+
computer is just keeping track of all these DOM nodes we don't need it to.
26+
That's what's called a memory leak. So it's really important we clean up after
27+
ourselves to avoid the performance problems associated with memory leaks.
28+
29+
NOTE: Because this extra credit is a completely different example, you've got
30+
another starting point file in: `src/exercise/05.extra-1.tsx`. 🐨 and 💰 will be
31+
there to help you get that working.
32+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "/vanilla-tilt.styles.css"

src/exercise/05.extra-1.tsx renamed to exercises/05.dom-side-effects/02.problem/index.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
// DOM Side-Effects
2-
// 💯 Side-effect cleanup
3-
// http://localhost:3000/isolated/exercise/05.tsx
4-
51
import * as React from 'react'
2+
import * as ReactDOM from 'react-dom/client'
63
import VanillaTilt from 'vanilla-tilt'
74

85
function Tilt({children}: {children: React.ReactNode}) {
@@ -43,7 +40,9 @@ function App() {
4340
)
4441
}
4542

46-
export {App}
43+
const rootEl = document.createElement('div')
44+
document.body.append(rootEl)
45+
ReactDOM.createRoot(rootEl).render(<App />)
4746

4847
/*
4948
eslint
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Side-Effect Cleanup
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@import "/vanilla-tilt.styles.css"

src/final/05.extra-1.tsx renamed to exercises/05.dom-side-effects/02.solution/index.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
// DOM Side-Effects
2-
// 💯 Side-effect cleanup
3-
// http://localhost:3000/isolated/final/05.tsx
4-
51
import * as React from 'react'
2+
import * as ReactDOM from 'react-dom/client'
63
import VanillaTilt from 'vanilla-tilt'
74

85
interface HTMLVanillaTiltElement extends HTMLDivElement {
@@ -40,4 +37,6 @@ function App() {
4037
)
4138
}
4239

43-
export {App}
40+
const rootEl = document.createElement('div')
41+
document.body.append(rootEl)
42+
ReactDOM.createRoot(rootEl).render(<App />)

0 commit comments

Comments
 (0)