Community

๐Ÿ•Š๏ธ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ React Hook ๊ฐ€์ด๋“œ

๊ณผ๊ฑฐ์—๋Š” React์—์„œ ์ƒํƒœ(state)๋ฅผ ๊ด€๋ฆฌํ•˜๋ ค๋ฉด ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง€๊ณ , ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋–จ์–ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด React Hook์ด ๋“ฑ์žฅํ•˜์˜€์œผ๋ฉฐ, ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ์ƒํƒœ ๊ด€๋ฆฌ์™€ ์ƒ๋ช…์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ์˜ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. ย  React Hook์ด ํ•„์š”ํ•œ ์ด์œ  * ๋” ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ: ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ๋ณด๋‹ค ์ฝ”๋“œ๊ฐ€ ์ง๊ด€์ ์ด๊ณ  ์งง์•„์ง * ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ ํ–ฅ์ƒ: ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ๊ฐ€ ์‰ฌ์›Œ์ง€๊ณ , ์žฌ์‚ฌ์šฉ์„ฑ์ด ์ฆ๊ฐ€ * ๋ถ€์ˆ˜ ํšจ๊ณผ ๊ด€๋ฆฌ๊ฐ€ ์šฉ์ด: useEffect๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ ๊ด€๋ฆฌ๋ฅผ ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ ๊ฐ€๋Šฅ ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž์˜ ์‹œ์„ ์—์„œ React Hook์„ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜๊ณ , ์‹ค๋ฌด์—์„œ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ย  ์ฃผ์š” React Hook ์†Œ๊ฐœ ย  [useState - ์ƒํƒœ ๊ด€๋ฆฌ] useState๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ์ƒํƒœ(state)๋ฅผ ์„ ์–ธํ•˜๊ณ  ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); // ์ƒํƒœ ์„ ์–ธ return ( ํ˜„์žฌ ์นด์šดํŠธ: {count} setCount(count + 1)}>์ฆ๊ฐ€ ); } โœ… useState๋Š” Java์—์„œ ๋ณ€์ˆ˜์™€ Setter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ React์—์„œ๋Š” ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋œ๋‹ค๋Š” ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ย  [useEffectย - ๋ถ€์ˆ˜ ํšจ๊ณผ(Site Effect) ์ฒ˜๋ฆฌ] useEffect๋Š”ย ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ(๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ, ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ๋“ฑ๋ก ๋“ฑ)๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” Hook ์ž…๋‹ˆ๋‹ค. import { useState, useEffect } from "react"; function Timer() { const [seconds, setSeconds] = useState(0); useEffect(() => { const interval = setInterval(() => { setSeconds((prev) => prev + 1); }, 1000); return () => clearInterval(interval); }, []); return ํƒ€์ด๋จธ: {seconds}์ดˆ; } โœ… useEffect๋Š” Spring์˜ @PostConstruct ๋ฐ @PreDestroy์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. * @PostConstruct: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋ Œ๋”๋ง๋  ๋•Œ ์‹คํ–‰ (useEffect์˜ ์ดˆ๊ธฐ ์‹คํ–‰) * @PreDestroy: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ ์ •๋ฆฌ (useEffect์˜ Cleanup) [useMemoย - ์„ฑ๋Šฅ ์ตœ์ ํ™”] useMemo๋Š” ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ๋ฐฉ์ง€ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. import { useState, useMemo } from "react"; function ExpensiveCalculation({ num }) { const squaredValue = useMemo(() => { console.log("์—ฐ์‚ฐ ์ˆ˜ํ–‰ ์ค‘..."); return num * num; }, [num]); // num์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ ๋‹ค์‹œ ๊ณ„์‚ฐ return ๊ณ„์‚ฐ ๊ฒฐ๊ณผ: {squaredValue}; } โœ… useMemo๋Š” Java์˜ ์บ์‹ฑ(Cache)๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. useMemo๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๊ฐ™์€ ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•ด ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ค„์ด๊ณ  ์บ์‹ฑ๋œ ๊ฐ’์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ย  [useCallbackย - ํ•จ์ˆ˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜] useCallback์€ useMemo์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ, ํ•จ์ˆ˜์˜ ์ฐธ์กฐ๊ฐ’์„ ์œ ์ง€ํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•˜๋Š” Hook์ž…๋‹ˆ๋‹ค. import { useState, useCallback } from "react"; function Parent() { const [count, setCount] = useState(0); const handleClick = useCallback(() => { setCount((prev) => prev + 1); }, []); return ์ฆ๊ฐ€; } โœ… useCallback์€ Spring์˜ Singleton ํŒจํ„ด๊ณผ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. ย  [useRefย - DOM ์ ‘๊ทผ & ์ƒํƒœ ์œ ์ง€] useRef๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ํŠน์ • ๊ฐ’์„ ์œ ์ง€ํ•˜๊ฑฐ๋‚˜, DOM ์š”์†Œ์— ์ง์ ‘ ์ ‘๊ทผํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. import { useRef } from "react"; function TextInput() { const inputRef = useRef(null); const focusInput = () => { inputRef.current.focus(); }; return ( ํฌ์ปค์Šค ์ด๋™ ); } โœ… useRef๋Š” Java์˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์™€ ๋น„์Šทํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ย  ๊ฒฐ๋ก  React Hook์€ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ ๊ด€๋ฆฌ์™€ ๋ถ€์ˆ˜ ํšจ๊ณผ ์ฒ˜๋ฆฌ๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. ๊ฐ Hook์˜ ํ™œ์šฉ ์‚ฌ๋ก€๋ฅผ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. * useState โ†’ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์˜ ์ƒํƒœ ๊ด€๋ฆฌ * useEffect โ†’ ๋ถ€์ˆ˜ ํšจ๊ณผ ์ฒ˜๋ฆฌ (API ํ˜ธ์ถœ, ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ๋“ฑ๋ก ๋“ฑ) * useMemo โ†’ ์—ฐ์‚ฐ ๊ฒฐ๊ณผ ์บ์‹ฑ (๋ถˆํ•„์š”ํ•œ ์žฌ๊ณ„์‚ฐ ๋ฐฉ์ง€) * useCallback โ†’ ํ•จ์ˆ˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ (๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง ๋ฐฉ์ง€) * useRef โ†’ DOM ์ ‘๊ทผ ๋ฐ ๊ฐ’ ์œ ์ง€ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด, React๋ฅผ API ์—ฐ๋™์ด ํ•„์š”ํ•œ ๋Œ€์‹œ๋ณด๋“œ๋‚˜ ์–ด๋“œ๋ฏผ UI ๊ฐœ๋ฐœ์— ํ™œ์šฉํ•  ๋•Œ๊ฐ€ ๋งŽ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. Hook์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ ์ž‘์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ, ์‹ค๋ฌด์—์„œ๋„ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

์•Œ๋ฆผ

์•Œ๋ฆผ์ด ์—†์Šต๋‹ˆ๋‹ค