Skip to content

Commit 6c538c0

Browse files
Finish Video
1 parent aef3343 commit 6c538c0

File tree

11 files changed

+182
-1
lines changed

11 files changed

+182
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import useOnlineStatus from "./useOnlineStatus"
2+
3+
export default function OnlineStatusComponent() {
4+
const online = useOnlineStatus()
5+
6+
return <div>{online.toString()}</div>
7+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { useState } from "react"
2+
import useEventListener from "../13-useEventListener/useEventListener"
3+
4+
export default function useOnlineStatus() {
5+
const [online, setOnline] = useState(navigator.onLine)
6+
7+
useEventListener("online", () => setOnline(navigator.onLine))
8+
useEventListener("offline", () => setOnline(navigator.onLine))
9+
10+
return online
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import useRenderCount from "./useRenderCount"
2+
import useToggle from "../1-useToggle/useToggle"
3+
4+
export default function RenderCountComponent() {
5+
const [boolean, toggle] = useToggle(false)
6+
7+
const renderCount = useRenderCount()
8+
9+
return (
10+
<>
11+
<div>{boolean.toString()}</div>
12+
<div>{renderCount}</div>
13+
<button onClick={toggle}>Toggle</button>
14+
</>
15+
)
16+
}
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { useEffect, useRef } from "react"
2+
3+
export default function useRenderCount() {
4+
const count = useRef(1)
5+
useEffect(() => count.current++)
6+
return count.current
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import useDebugInformation from "./useDebugInformation"
2+
import useToggle from "../1-useToggle/useToggle"
3+
import { useState } from "react"
4+
5+
export default function DebugInformationComponent() {
6+
const [boolean, toggle] = useToggle(false)
7+
const [count, setCount] = useState(0)
8+
9+
return (
10+
<>
11+
<ChildComponent boolean={boolean} count={count} />
12+
<button onClick={toggle}>Toggle</button>
13+
<button onClick={() => setCount(prevCount => prevCount + 1)}>
14+
Increment
15+
</button>
16+
</>
17+
)
18+
}
19+
20+
function ChildComponent(props) {
21+
const info = useDebugInformation("ChildComponent", props)
22+
23+
return (
24+
<>
25+
<div>{props.boolean.toString()}</div>
26+
<div>{props.count}</div>
27+
<div>{JSON.stringify(info, null, 2)}</div>
28+
</>
29+
)
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useEffect, useRef } from "react"
2+
import useRenderCount from "../27-useRenderCount/useRenderCount"
3+
4+
export default function useDebugInformation(componentName, props) {
5+
const count = useRenderCount()
6+
const changedProps = useRef({})
7+
const previousProps = useRef(props)
8+
const lastRenderTimestamp = useRef(Date.now())
9+
10+
const propKeys = Object.keys({ ...props, ...previousProps })
11+
changedProps.current = propKeys.reduce((obj, key) => {
12+
if (props[key] === previousProps.current[key]) return obj
13+
return {
14+
...obj,
15+
[key]: { previous: previousProps.current[key], current: props[key] },
16+
}
17+
}, {})
18+
const info = {
19+
count,
20+
changedProps: changedProps.current,
21+
timeSinceLastRender: Date.now() - lastRenderTimestamp.current,
22+
lastRenderTimestamp: lastRenderTimestamp.current,
23+
}
24+
25+
useEffect(() => {
26+
previousProps.current = props
27+
lastRenderTimestamp.current = Date.now()
28+
console.log("[debug-info]", componentName, info)
29+
})
30+
31+
return info
32+
}

src/29-useHover/HoverComponent.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { useRef } from "react"
2+
import useHover from "./useHover"
3+
4+
export default function HoverComponent() {
5+
const elementRef = useRef()
6+
const hovered = useHover(elementRef)
7+
8+
return (
9+
<div
10+
ref={elementRef}
11+
style={{
12+
backgroundColor: hovered ? "blue" : "red",
13+
width: "100px",
14+
height: "100px",
15+
position: "absolute",
16+
top: "calc(50% - 50px)",
17+
left: "calc(50% - 50px)",
18+
}}
19+
/>
20+
)
21+
}

src/29-useHover/useHover.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { useState } from "react"
2+
import useEventListener from "../13-useEventListener/useEventListener"
3+
4+
export default function useHover(ref) {
5+
const [hovered, setHovered] = useState(false)
6+
7+
useEventListener("mouseover", () => setHovered(true), ref.current)
8+
useEventListener("mouseout", () => setHovered(false), ref.current)
9+
10+
return hovered
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { useRef } from "react"
2+
import useLongPress from "./useLongPress"
3+
4+
export default function LongPressComponent() {
5+
const elementRef = useRef()
6+
useLongPress(elementRef, () => alert("Long Press"))
7+
8+
return (
9+
<div
10+
ref={elementRef}
11+
style={{
12+
backgroundColor: "red",
13+
width: "100px",
14+
height: "100px",
15+
position: "absolute",
16+
top: "calc(50% - 50px)",
17+
left: "calc(50% - 50px)",
18+
}}
19+
/>
20+
)
21+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import useEventListener from "../13-useEventListener/useEventListener"
2+
import useTimeout from "../2-useTimeout/useTimeout"
3+
import useEffectOnce from "../20-useEffectOnce/useEffectOnce"
4+
5+
export default function useLongPress(ref, cb, { delay = 250 } = {}) {
6+
const { reset, clear } = useTimeout(cb, delay)
7+
useEffectOnce(clear)
8+
9+
useEventListener("mousedown", reset, ref.current)
10+
useEventListener("touchstart", reset, ref.current)
11+
12+
useEventListener("mouseup", clear, ref.current)
13+
useEventListener("mouseleave", clear, ref.current)
14+
useEventListener("touchend", clear, ref.current)
15+
}

src/App.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ import DarkModeComponent from "./22-useDarkMode/DarkModeComponent"
2323
import CopyToClipboardComponent from "./23-useCopyToClipboard/CopyToClipboardComponent"
2424
import CookieComponent from "./24-useCookie/CookieComponent"
2525
import TranslationComponent from "./25-useTranslation/TranslationComponent"
26+
import OnlineStatusComponent from "./26-useOnlineStatus/OnlineStatusComponent"
27+
import RenderCountComponent from "./27-useRenderCount/RenderCountComponent"
28+
import DebugInformationComponent from "./28-useDebugInformation/DebugInformationComponent"
29+
import HoverComponent from "./29-useHover/HoverComponent"
30+
import LongPressComponent from "./30-useLongPress.js/LongPressComponent"
2631

2732
function App() {
2833
// return <ToggleComponent />
@@ -49,7 +54,12 @@ function App() {
4954
// return <DarkModeComponent />
5055
// return <CopyToClipboardComponent />
5156
// return <CookieComponent />
52-
return <TranslationComponent />
57+
// return <TranslationComponent />
58+
// return <OnlineStatusComponent />
59+
// return <RenderCountComponent />
60+
// return <DebugInformationComponent />
61+
// return <HoverComponent />
62+
return <LongPressComponent />
5363
}
5464

5565
export default App

0 commit comments

Comments
 (0)