-
๋ฆฌ์กํธ์์ requestAnimationFrame ์ฌ์ฉ ์ ์ฃผ์ํ ์ TECH 2024. 3. 17. 20:41
๋ฆฌ์กํธ์์
requestAnimationFrame
API๋ฅผ ์ฌ์ฉํ๋ฉด์ ๊ฒช์๋ ๋ฌธ์ ๋ฅผ ๊ณต์ ํด ๋ณด๋ ค๊ณ ํฉ๋๋ค.๐ ๋ฌธ์ ๊ฐ ๋์๋ ์ฝ๋
function AnimationSection() { const [count, setCount] = useState(0); const text = 'welcome to ttaerrim world'.toUpperCase(); const textRef = useRef<HTMLDivElement>(null); const animate = () => { const width = textRef.current?.scrollWidth; if (width) { if (count > width) { setCount(0); } else { setCount((c) => c + 10); } } requestRef.current = requestAnimationFrame(animate); }; useEffect(() => { requestRef.current = requestAnimationFrame(animate); return () => cancelAnimationFrame(requestRef.current); }, []); // ... ์๋ต }
์ ํ๋ธ์์ ๋ณธ ๋ง์๋ ์ฝ๋ฉ๋์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก 5๋ถ๋ง์ ํ ์คํธ ์คํฌ๋กค ์ ๋๋ฉ์ด์ ํจ๊ณผ(text marquee effect) ๋ง์คํฐํ๊ธฐ๋ฅผ ๋ณด๊ณ ์๋ฐ์คํฌ๋ฆฝํธ ์์ ๋ฅผ ๋ฆฌ์กํธ ์ฝ๋๋ก ์์ฑํ์ฌ ์ ๋๋ฉ์ด์ ์ ๋์ํ๊ณ ์ถ์์ต๋๋ค.
์์์์ ์ค๋ช ํ๋ ๋ฐฉ์๋๋ก
element
์width
๊ฐcount
๋ฅผ ์ด๊ณผํ๊ฒ ๋๋ฉดcount
๋ฅผ 0์ผ๋ก ๋ณ๊ฒฝํ์ฌ ๋์์์ด ํ๋ฅด๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๋ ์ ๋๋ฉ์ด์ ์ ๋ง๋๋ ๊ฒ์ด ๋ชฉํ์์ผ๋ ์์๋๋ก ๋์ํ์ง ์์์ต๋๋ค.์ด์ ๋
useEffect
๋ด์์๋ ์ฌ์ฉํ๋count
๋ณ์๊ฐsetCount
๋ก ๋ณ๊ฒฝํ๋๋ผ๋ ์ด๊ธฐ๊ฐ 0์์ ๋ณ๊ฒฝ๋์ง ์๋ ํ์์ด ์์์ต๋๋ค.๊ทธ๋ ๊ธฐ ๋๋ฌธ์ if๋ฌธ์
(count > width)
์กฐ๊ฑด์ ์ ํ ์ ์์๋ ๊ตฌ์กฐ์์ต๋๋ค.โ
useEffect
๊ฐ ์ด๋ ๊ฒ ๋์ํ๋ ์ด์ ๋ ๋ฌด์์ผ๊น์?useEffect
์ ๋ ๋ฒ์งธ ์ธ์๋ก ๋น ๋ฐฐ์ด์ ์ ๋ฌํ๋ฉดuseEffect
๋ก ์ ๋ฌํ๋ ์ฝ๋ฐฑํจ์๋ฅผ ํ ๋ฒ๋ง ์คํํ ์ ์์ต๋๋ค.๊ทธ๋ฐ๋ฐ ์ด๋ ๊ฒ ํ๋ฉด ์ ๋๋ฉ์ด์ ์ค์ ์ฌ๋ฐ๋ฅธ ์ํ๋ฅผ ์ ์งํ ์ ์์ต๋๋ค.
useEffect
์ dependency๋ก ๋น ๋ฐฐ์ด์ ์ ๋ฌํ๋ ๊ฒ์ ๋ฆฌ์กํธ๋ ์ํ๋ฅผ ์ต์ ์ผ๋ก ์ ์งํ ํ์๊ฐ ์๋ค๋ ์๋ฏธ๋ก ํด์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.๋ฐ๋ผ์ ๋น ๋ฐฐ์ด์ dependecy๋ก ๊ฐ์ง๋
useEffect
๋ด์์ state์ ๊ฐ์ ๊ฐ์ ธ์ค๋ฉด ํญ์ ์ด๊ธฐ๊ฐ์๋ง ์ ๊ทผํ ์ ์์ต๋๋ค.๋ฐ๋ผ์ ๋ค์๊ณผ ๊ฐ์ด ์ ๋๋ฉ์ด์ ์ฝ๋๋ฅผ ์์ ํ์ต๋๋ค.
function AnimationSection() { const [count, setCount] = useState(0); const text = 'welcome to ttaerrim world'.toUpperCase(); const textRef = useRef<HTMLDivElement>(null); const requestRef = useRef<number>(0); const previousTimeRef = useRef<number>(0); const animate = (time: DOMHighResTimeStamp) => { const width = textRef.current?.scrollWidth; if (previousTimeRef.current !== undefined && width) { const deltaTime = Math.floor(time - previousTimeRef.current); setCount((prevCount) => (prevCount + deltaTime * 0.2) % width); } previousTimeRef.current = time; requestRef.current = requestAnimationFrame(animate); }; useEffect(() => { requestRef.current = requestAnimationFrame(animate); return () => cancelAnimationFrame(requestRef.current); }, []); // ์๋ต }
useEffect
๋ด์์๋ state์ ์ด๊ธฐ๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์setCount
ํจ์๋setCount((count + deltaTime * 0.2) % width)
์ฒ๋ผ ์ฌ์ฉํ๋ฉด ๋ ๋๊ฐ์ ๊ฐ์count
๋ก ์ง์ ํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.์ต์ ์ ์ํ ๊ฐ์ ์ฌ์ฉํ๋ ค๋ฉด
setState
๋ก ํจ์๋ฅผ ๋๊ฒจ ์ค๋๋ค.setState(prevState ⇒ prevState + value)
์ด๋ฐ ์์ผ๋ก, ํ์ฌ ์ํ๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ฐ์ ์ ๋ฌํ์ฌ ์ ์ฉํ๋ฉด ์ํ ๊ฐ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค.
์ ๋๋ฉ์ด์ ๋์์ ์ฌ์ฉ๋๋ ์ํ ๊ฐ ์ค ๊ฐ์ด ๋ณ๊ฒฝ๋๋๋ผ๋ ๋ ๋๋ง์ํค์ง ์๊ณ ์ถ์ ๋๊ฐ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ์๋
useRef
๋ฅผ ์ฌ์ฉํฉ๋๋ค.useRef
๋ ๋ณ๊ฒฝ๋๋๋ผ๋ ๋ ๋๋ง์ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.์ ๋๋ฉ์ด์ ์ cleanup ํ ๋ ๊ณ์ ๋ณ๊ฒฝ๋๋
reqeustAnimationFrame
์ id๋ฅผ ์ ์ฅํด ๋์ด์ผ ํ๊ณ , ๊ฒฝ๊ณผ๋ ์๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ ๋๋ฉ์ด์ ์ ์ ์ฉํ๋ ๊ฒฝ์ฐ ํ์์คํฌํ๋ฅผ ๊ธฐ์ตํด์ผ ํฉ๋๋ค. ์ด ๋ ๋ณ์๋ฅผuseRef
๋ฅผ ์ฌ์ฉํดrequestRef
์previousTimeRef
์ ์ ์ฅํด ์ฌ์ฉํ์ต๋๋ค.๐ ์ฐธ๊ณ
Using requestAnimationFrame with React Hooks | CSS-Tricks - CSS-Tricks
'TECH' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํ๋ฉด ๋๋น๋ฅผ ์ด๊ณผํ์ง ์๋ ํดํ ๋ง๋ค๊ธฐ w.React (0) 2024.04.28 React Hook Form์ ์๋ก ๋น์ทํ ๊ธฐ๋ฅ๋ค์ ๋น๊ตํด ๋ณด์ (0) 2024.02.03 useState, ํด๋ก์ ๋ฅผ ํ์ฉํ์ฌ ๋์ํ๋ค๊ณ ? (0) 2024.01.27 React์์ Event Handler๋ ์ด๋ป๊ฒ ๋์ํ ๊น์? (0) 2024.01.11 Zero Runtime CSS-in-JS์ ๋ํด ์์๋ณด์ (1) 2024.01.06