๐จ 08. useRef: ๋ ๋๋ง์ ํผํ๋ ๋น๋ฐ ๊ธ๊ณ
๐ ๊ฐ์
ํญ์ ์ต์ ๊ฐ์ ์ ์งํด์ผ ํ์ง๋ง ํ๋ฉด์ด ๋ฆฌ๋ ๋๋ง๋๋ ๊ฒ์ ์์น ์์ ๋, useRef๊ฐ ์ด๋ค ์ญํ ์ ํ๋์ง ๋ด๋ถ ์๋ฆฌ์ ํจ๊ป ํํค์นฉ๋๋ค.
๐ฏ ์ด ์น์ ์ ์ฝ๊ณ ๋๋ฉด:
useRef๊ฐ ๋จ์ํ<input>์ฐฝ์ ํฌ์ปค์ค๋ฅผ ๋ง์ถ๋ DOM ์ฐ๊ฒฐ ๋๊ตฌ๊ฐ ์๋์ ์๊ฒ ๋๋ค.- ์ํ(
useState)์ ์ฐธ์กฐ(useRef)์ ๋ณธ์ง์ ์ธ ๊ธฐ์ ์ ์ฐจ์ด๋ฅผ ์ค๋ ์ท vs ์๊ตฌ ๋ณ์ ๋ฉํ ๋ชจ๋ธ๋ก ๊ตฌ๋ถํ ์ ์๋ค.- ํ๋ฉด ์ ๋ฐ์ดํธ ์์ด ๋ถ๋ณํ๋ ๊ฐ์ ์๋ฐํ ์ถ์ ํ๊ณ ์ถ์ ๋(ํ์ด๋จธ ID ์ ์ฅ, ์ด์ ์ํ ์ถ์ )
useRef๋ฅผ ํ๋ฅญํ๊ฒ ์ค๊ณํ ์ ์๋ค.
๐ ๋ชฉ์ฐจ
- ๐ค ์ ์์์ผ ํ๋๊ฐ: ์๋์น๋ ์ปดํฌ๋ํธ๋ฅผ ๊ฒฌ๋๋ ๋ป
- ๐๏ธ ๋น์ ๋ก ๋จผ์ ์ดํดํ๊ธฐ
- ๐งฉ ์ค์ ๋ฌด๊ธฐํ: ์จ๊ฒจ์ง ๋ณ์๋ค ๋ค๋ฃจ๊ธฐ
- ๐ฅ ์๋ฌ ํด๊ฒฐ ์นดํ๋ก๊ทธ
๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 10๋ถ / ํต์ฌ ํํธ: 7๋ถ
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
- ์์ฒ (์ ์
): "ํ์ด๋จธ ์คํฑ์์น๋ฅผ ๋ง๋ค๊ณ ์๋๋ฐ์! ์์ ๋ฒํผ์ ๋๋ ๋๋ฐ ์ค์ง ๋ฒํผ์ ๋๋ฅผ ๋ ํ์ด๋จธ๊ฐ ์ ๋ฉ์ถ๊ณ ๊ณ์ ๊ฐ์! ์ธํฐ๋ฒ ์์ด๋(ID)๋ฅผ
useState์ ๋ด์๋๋๋ฐ ๋ญ๊ฐ ๋ฌธ์ ์ฃ ?" - ์ํธ(๋ฆฌ๋): "์์ฒ ๋, ํ๋ฉด์ ๊ทธ ์ซ์ ๋ณด์ฌ์ฃผ์ค ๊ฑด๊ฐ์? ์ ๋ณด์ฌ์ค ๋ณ์๋ผ๋ฉด ๊ณผ๋ํ ๋ ๋๋ง(
useState) ํฐ๋จ๋ฆฌ์ง ๋ง๊ณ ์กฐ์ฉํ ๋ท์ฃผ๋จธ๋(useRef)์ ๋ฃ๊ณ ๋ค๋๋ผ๊ณ ์์ ์ ๋ง์๋๋ ธ์ ํ ๋ฐ์."
๐ค ์ ์์์ผ ํ๋๊ฐ: ์๋์น๋ ์ปดํฌ๋ํธ๋ฅผ ๊ฒฌ๋๋ ๋ป
๋๋ถ๋ถ์ React ์์ ๋ฌธ์๋ฅผ ๋ณด๋ฉด useRef๋ฅผ ์ฒ์ ์๊ฐํ ๋ ๊ผญ "DOM ์กฐ์(<input ref={myRef}>)์ ์ํ ๊ฐ๊ณ ๋ฆฌ์
๋๋ค~" ๋ผ๊ณ ๊ฐ๋ฅด์ณ. ํ์ง๋ง ์ด๊ฑด useRef ๋ฅ๋ ฅ์น ์ค ๋น์ฐ์ ์ผ๊ฐ๋ ์ ๋๋ 10%์ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ๋ถ๊ณผํด.
๐ค ์ ๊น, ๋จผ์ ์๊ฐํด๋ด
์คํฑ์์น ์ฝ๋๋ฅผ ์ง๋ ค๊ณ ํด. ํ์ด๋จธ๋ฅผ ๋ฉ์ถ๋ ค๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ์clearInterval(์์ด๋๊ณ ์ ๋ฒํธ)๊ฐ ํ์ํ์ง.
์ด ๊ณ ์ ๋ฒํธ๋ฅผ ๋ ๋๋ง ์ฌ์ดํด์ด ๋์๋ ๊ธฐ์ตํ๋ ค๋ฉด ์ด๋๋ค ๋ณ์๋ฅผ ๋ง๋ค์ด์ผ ํ ๊น?
// โ ์์ฒ ์ด์ ์ํํ ์ ํ (์ํ ์ค๋จ์ฉ)
function Stopwatch() {
const [seconds, setSeconds] = useState(0);
const [timerId, setTimerId] = useState(null); // ๐จ ํ๋ฉด์ ๊ทธ๋ฆฌ์ง๋ ์์ ๊ฑด๋ฐ ๊ตณ์ด ์ํ๋ก ๋ง๋ฆ!
const handleStart = () => {
const id = setInterval(() => setSeconds(s => s + 1), 1000);
setTimerId(id); // ๋ถํ์ํ๊ฒ ์ํ ๊ฐฑ์ ๋ฐ๋! -> ๋ฌด์๋ฏธํ ๋ ๋๋ง 1ํ ์ถ๊ฐ ๋ฐ์ฌ!
};
const handleStop = () => {
clearInterval(timerId);
};
return (
<div>
<p>๊ฒฝ๊ณผ ์๊ฐ: {seconds}์ด</p>
<button onClick={handleStart}>์์</button>
<button onClick={handleStop}>๋ฉ์ถฐ!</button>
</div>
);
}์์ฒ ์ด ์ฝ๋๋ ์ผํ ๋ฌธ์ ๊ฐ ์์ด ๋ณด์ฌ(๊ตฌ๋์ ๋๋๊น).
ํ์ง๋ง ์ด๊ฑด ๋ถํ์ํ ๋ ๋๋ง์ ๋ง๋๋ ์ฝ๋์
๋๋ค. timerId๋ ํ๋ฉด UI์ ํฝ์
๋จ ํ๋๋ ๋ฐ๊พธ์ง ์๋๋ฐ, ์๋ฅผ ๊ฐฑ์ ํ๋ต์๊ณ setTimerId(id)๋ฅผ ํธ์ถํ๋ ์๊ฐ ๋ฆฌ์กํธ๋ ์ํ ๋ณ๊ฒฝ์ผ๋ก ๋ณด๊ณ ์ปดํฌ๋ํธ๋ฅผ ํ ๋ฒ ๋ ๋ ๋๋งํฉ๋๋ค.
์ฐ๋ฆฌ์๊ฒ "๊ฐ์ ์์ ํ๊ฒ ์ ์ฅํ๋, ๊ฐ์ด ๋ฐ๋๋ค๊ณ ๋ ๋๋ง์ ์์ฒญํ์ง๋ ์๋ ๋น๋ฐ ์ฐฝ๊ณ " ๊ฐ ํ์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ ๋ฐ๋ก useRef์ ๋ณธ์ง์
๋๋ค.
๐๏ธ ๋น์ ๋ก ๋จผ์ ์ดํดํ๊ธฐ
๐ง 5์ด์๊ฒ ์ค๋ช ํ๋ค๋ฉด?
useState๋ ๋ฐฉ์ก๊ตญ ๋ง์ดํฌ์ผ. ๋ง์ดํฌ์ ๋๊ณ ์ซ์๋ฅผ ๋ฐ๊พธ๋ฉด ์จ ๋๋ค ๋ง์ ์ฌ๋๋ค(์ปดํฌ๋ํธ๋ค)์ด ๋ค ๋ฆฌ์ ๋ผ์ ๋ค์ ๋ค์ผ๋ฌ ๊ด์ฅ์ผ๋ก ๋ชจ์ด์ง(๋ฆฌ๋ ๋๋ง ํํฐ).
useRef๋ ๋ค ๋ฐ์ง๋จ ๊น์์ด ์จ๊ฒจ๋์ ์์ ๊ธ๊ณ ๋ฐ์ค(current์์ฑ) ์ผ.
๋ค๊ฐ ๋ชฐ๋ ๊ธ๊ณ ๋ฌธ์ ์ด๊ณcurrent๊ณต๊ฐ ์์ ๋์ 100๋ง ์์ผ๋ก ๋ฐ๊พธ๋ 10์์ผ๋ก ์ชผ๊ฐ๋ ๋๋ค ์ฌ๋๋ค์ ์๋ฌด๋ ๋ชจ๋ฅด๊ณ ์๋ฌด ์๋ฆฌ๋ ์ ๋(๋ฆฌ๋ ๋๋ง ๋ฌด์).
ํ์ง๋ง ์ปดํฌ๋ํธ๊ฐ ์ฌ๋ฌ ๋ฒ ๋ค์ ๋ ๋๋ง๋์ด๋, ๊ทธ ๋ฐ์ง๋จ ์ ๊ธ๊ณ ์์๋ ์ปดํฌ๋ํธ๊ฐ ์ด์์๋ ๊ธฐ๊ฐ ๋ด๋ด ์๊ตฌ์ ์ผ๋ก ๋ณด์กด๋๋ฉด์ ์ ๋ ์ ๋ณด๊ฐ ์ฆ๋ฐํ์ง ์์.
โ
ํต์ฌ ์๋ฆฌ:
React ๊ณต์ ๋ฌธ์์ ํํ๋๋ก, useRef๋ { current: initialValue } ํํ์ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋ค์ ๋ ๋์์๋ ๋๋ ค์ค๋ค. current๋ ์ง์ ๋ฐ๊ฟ ์ ์์ง๋ง, ์ด ๋ณ๊ฒฝ์ ์ํ ๋ณ๊ฒฝ ์ ํธ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ React๊ฐ ๋ค์ ๋ ๋๋งํ์ง ์๋๋ค.
๊ทธ๋์ useRef๋ ๋ ๋๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๊พธ์ง ์๋ ๊ฐ์ ์ด์ธ๋ฆฐ๋ค. ํ์ด๋จธ ID, ์ด์ ์คํฌ๋กค ์์น, DOM ๋
ธ๋์ฒ๋ผ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ Effect์์ ์ฝ๊ณ ์ฐ๋ ๊ฐ์ ์ข์ง๋ง, ํ๋ฉด์ ๋ณด์ฌ์ค ๊ฐ์ useState๋ก ๊ด๋ฆฌํด์ผ ํ๋ค.
๐งฉ ์ค์ ๋ฌด๊ธฐํ: ์จ๊ฒจ์ง ๋ณ์๋ค ๋ค๋ฃจ๊ธฐ
โ
์ํธ์ ์๋ฒฝํ ๋ฆฌํฉํ ๋ง: current ๋ฌด๊ธฐ๊ณ ์ฌ์ฉ
- UI(ํ๋ฉด)์ ๊ทธ๋ฆด ๋ด์ฉ์ -> ๋ ๋๋ง์ ๋ฐ์ํ๋
useState๋ง์ดํฌ์ ๋ด๋๋ค (seconds) - ๋ด๋ถ ๋ก์ง ํต์ ์ฉ(์๋, ํ์ด๋จธ ์์ด๋, ๋๋๊ทธ ์คํฌ๋กค ํฝ์
์ด์ ์์น ๋ฑ) ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ฐ์ดํฐ๋ -> ๋น๋ฐ ๊ธ๊ณ
useRef์ ๋ด์ ๋ชฐ๋ ๊ด๋ฆฌํ๋ค (timerRef)
// โ
์ฐ์ํ ๊ณ ์ฑ๋ฅ ๋ ๋๋ง ์ฝ๋ (Pro Approach)
function Stopwatch() {
const [seconds, setSeconds] = useState(0); // ํ๋ฉด UI์ ์ง๊ฒฐ๋ ์ ์ผํ ์น๊ตฌ
const timerRef = useRef(null); // ๐ฏ ๋ฆฌ๋ ๋๋ง ๊ฐ์ ๋ฉด์ ๊ถ ๋ฐ๊ธ!
const handleStart = () => {
if (timerRef.current) return; // ์ด๋ฏธ ๋๊ณ ์์ผ๋ฉด ๋ฐฉ์ด!
// ์ด ๊ฐ์ ๊ฐฑ์ ํด๋ ๋ฆฌ์กํธ๋ ๋๋ ๊น์ง ์ ํฉ๋๋ค. ๋ถํ์ํ ๋ ๋๋ง 0ํ ๋ฌ์ฑ.
timerRef.current = setInterval(() => setSeconds(s => s + 1), 1000);
};
const handleStop = () => {
clearInterval(timerRef.current);
timerRef.current = null; // ์ด๊ธฐํ
};
return (
<div>
<p>๊ฒฝ๊ณผ ์๊ฐ: {seconds}์ด</p>
<button onClick={handleStart}>์์</button>
<button onClick={handleStop}>๋ฉ์ถฐ!</button>
</div>
);
}๊น๋ํฉ๋๋ค. setTimerId(id)๋ก ๋ ๋๋ง์ ํ ๋ฒ ๋ ๋ง๋ค ํ์๊ฐ ์์ด์ก์ด.
timerRef.current = ... ํ ๋น๋ฌธ์ React์๊ฒ ๋ ๋๋ง์ ์์ฒญํ์ง ์์ผ๋ฏ๋ก, ํ์ด๋จธ ์ ์ด ๊ฐ์ฒ๋ผ UI์ ์ง์ ์ฐ๊ฒฐ๋์ง ์์ ๋ฐ์ดํฐ์ ์ ํฉํฉ๋๋ค.
๐ฅ ์๋ฌ ํด๊ฒฐ ์นดํ๋ก๊ทธ
โ useRef ๊ธ๊ณ ์์ ๊ฐ์ ํ๋ฉด์ ๋ ธ์ถ์ํค๋ ์ฌ์๋๊ฐ
์ธ์ ๋์ค๋๊ฐ?
const countRef = useRef(0);
const handleAdd = () => {
countRef.current += 1;
// ๐ฅ ์์ฒ : "ํํ ๋๋ ๋๋ฐ ํ๋ฉด ์ซ์๊ฐ ์ ๋ฐ๋์์์!"
};
// ... <button onClick={handleAdd}>๋๋น ๋๋ฆ ํ์: {countRef.current}</button> ...์์ธ: useRef๊ฐ ๋ ๋๋ง์ ๋ฐ๋์ํค์ง ์๋๋ค๋ ๊ฒ์ ์ธ์งํ์ง ๋ชปํ๊ณ ํ๋ฉด UI(JSX ๋ฐํ ๊ณต๊ฐ)์ ๋ฃ์ ๊ฑฐ์ผ. ๋ฒํผ์ ๋๋ฌ current๋ฅผ ๋ฐ๊ฟ๋ React๋ ์ํ ๋ณ๊ฒฝ ์ ํธ๋ฅผ ๋ฐ์ง ์์๊ธฐ ๋๋ฌธ์ ํ๋ฉด์ ๋ค์ ๊ณ์ฐํ์ง ์๋๋ค.
๊ทธ๋ฌ๋ค๊ฐ ์ฐ์ฐํ ๋ค๋ฅธ ์ํ(State)๊ฐ setState๋์ด ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง๋๋ฉด, ref์ ์์ฌ ์๋ ๊ฐ์ด ๊ทธ์ ์ผ ํ๋ฉด์ ๋ฐ์๋ ์ ์๋ค. ์ฌ์ฉ์๋ "๋ฐฉ๊ธ ๋๋ฅธ ๊ฐ์ด ์ ์ด์ ๋ํ๋์ง?"๋ผ๊ณ ํผ๋์ ๊ฒช๋๋ค.
ํด๊ฒฐ์ฑ
:
useRef์ current ์์ฑ๊ฐ์ ๋ ๋๋ง ๊ฒฐ๊ณผ๋ฌผ(<p>{์ฌ๊ธฐ}</p>)์ ํต์ฌ ๋ฐ์ดํฐ๋ก ์ฐ์ง ๋ง์ธ์. UI์ ์ง๊ฒฐ๋๋ ๋ฐ์ดํฐ๋ผ๋ฉด ๋ฐ๋์ useState๋ฅผ ๊ณ ๋ฅด์ญ์์ค.
"๋ฐ์ดํฐ์ ๋ณ๊ฒฝ์ด ์๊ฐ์ ์ธ ๋ณํ๋ฅผ ๋ณ๋๊ฐ?" -> YES๋ฉด State, NO๋ฉด Ref์
๋๋ค.
๐ ์ด๋ฒ์ ๋ฐฐ์ด ๋ด์ฉ ์ด์ ๋ฆฌ
| ๋๊ตฌ์ ๋ณธ์ง | useState (๋ง์ดํฌ) | useRef (๋น๋ฐ ๊ธ๊ณ ) |
|---|---|---|
| ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋ฉด? | ์ฆ์ ๋ฆฌ๋ ๋๋ง ๋ฐ์ (UI ์ ๋ฐ์ดํธ O) | ๋ฆฌ๋ ๋๋ง ๋ฐ์ ์ ํจ (ํ๋ฉด ์ผ์ด์์ X) |
| ๋ ๋๋ง ๊ฐ ๋ฐ์ดํฐ ์ ์ง | O (ํ์ง๋ง ๋ ๋๋ง๋ง๋ค ๊ฐ์ ์ค๋ ์ท ๊ณ ์ ๋ณต์ฌํด ์ค) | O (์ธ์ ๊ฐ๋ฆฌ์ผ๋ '๋์ผํ ์ต์ ์ฃผ์ ํ ๋ฒํผ' ์ฐธ์กฐ) |
| ์ด๋์ ์ด์ธ๋ฆฌ๋๊ฐ? | ์ธํ ์ ๋ ฅ ํ ์คํธ, ๋ชจ๋ฌ์ฐฝ(T/F), ๋ฒํผ ์ปฌ๋ฌ ๋ฑ ํ๋ฉด ๊ทธ๋ฆด ๋ | ํ์ด๋จธ ์์ด๋ ์ฅ๊ธฐ, DOM ์์ ํฌ์ปค์ค ์กฐ์ํ๊ธฐ, ์ด์ (Prev) ๊ฐ ๋ชฐ๋ ์ ์ฅํ๊ธฐ ๋ฑ |
๐ก ํ ์ค๋ก ๊ธฐ์ตํ๊ธฐ
"๋๋ง์ ์ด ์์คํ ๋ฐ์ดํฐ๊ฐ ๋ฐ๋์์ ๋, ์จ ๋ง์์ ๋ค์ง์ด์๊ณ ํ๋ฉด์ ์๋ก๊ณ ์นจํ๊ณ ์ถ์๊ฐ?" ์ด ๋ฌธํญ์ "์๋์, ๊ทธ๋ฅ ๋ฐ์ดํฐ ์ซ์๋ง ํผ์ ๊ธฐ์ตํด์ฃผ๋ฉด ๋ผ์."๋ผ๊ณ ์ธ์น๊ณ ์ถ๋ค๋ฉด ๋ฌด์กฐ๊ฑด ๋ง์ค์ด์ง ๋ง๊ณuseRef์์ฃผ๋จธ๋๋ฅผ ์ง๋ผ.
๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
Q1. useState ๋์ useRef๋ฅผ ์ ํํ๋ ๊ฒ์ด ๊ฐ์ฅ ์๋ฒฝํ ๋ฒ ์คํธ ํ๋ํฐ์ค(Best Practice)๋ก ๋ถํฉํ๋ ์ํฉ์ ํ๋ ๊ณ ๋ฅด์ธ์.
- A) ์ฌ์ฉ์๊ฐ ์ผํ๋ชฐ ๊ฒ์์ฐฝ์์ ํ์ดํํ๊ณ ์๋ ์ค์๊ฐ ๊ฒ์์ด ํ ์คํธ ๊ฐ์ ์ ์งํ๊ณ ์ถ์ ๋.
- B) ํ์ฌ ๋ก๊ทธ์ธํ ํ ํฐ์ด ์ ํจํ ์ ์ ์ธ์ง์ ๋ํ boolean(T/F) ๊ฐ์ ์ ์ฅํ๊ณ ๊ถํ ์๋ฌ ๋ชจ๋ฌ์ ๋์ธ ๋.
- C) ์ปดํฌ๋ํธ ๋ง์ดํธ ์ดํ 30์ด ๋์ ์๋ฌด ํด๋ฆญ๋ ํ์ง ์์ผ๋ฉด ๊ฒฝ๊ณ ํ์
์ ๋์์ค
setTimeoutํจ์์ ์์ฝ ๊ณ ์ ํต์ ์์ด๋(ID)๋ฅผ ์ ์ฅํ ๋. - D) ์ฌ์ฉ์์ ํ์ฌ ์ผํ ์นดํธ์ ๋ด๊ธด ๋ฌผํ ์ด ๊ฒฐ์ ๊ธ์ก์ ์ค์๊ฐ ๊ณ์ฐํ์ฌ ์ฐ์ธก ํ๋จ ์์์ฆ์ ๋ณด์ฌ์ค ๋.
โ ์ ๋ต: C
๐ก ์์ธ ํด์ค: ๋ ๋๋ง ํธ๋ฆฌ๊ฑฐ ์ฌ๋ถ๋ง ๊ตฌ์ํ ์ค ์๋ฉด ๋ฉ๋๋ค! A์ ๊ฒ์์ด, B์ ๋ชจ๋ฌ T/F, D์ ์นดํธ ๊ฒฐ์ ์ก ์ซ์๋ ์ ๋ถ "๊ฐ์ด ํ ๋ฒ์ด๋ผ๋ ๋ฐ๋๋ฉด ํ๋ฉด์ ํฝ์
UI๊ฐ ์ ์ ๋์์์ ์ฆ์์ฆ์ ๋ณ๊ฒฝ๋์ด์ผ ํ๋" UI ์ง๊ฒฐํ ๋ฐ์ดํฐ์ด๋ฏ๋ก ๋ฌด์กฐ๊ฑด useState์ ์์ญ์
๋๋ค.
๋ฐ๋ฉด C์ ํ์ด๋จธ ์์ด๋๋ ๋จ์ ์ ์ ์ซ์(1, 2, 3...)์ผ ๋ฟ ๋ธ๋ผ์ฐ์ DOM ์ด๋์๋ ์ถ๋ ฅ๋ ์ผ์ด ์์ผ๋ฉฐ, ์ค์ง ํด๋ฆฐ์
์ clearTimeout(ID) ์ฒ๋ฆฌ ๋ก์ง์ ํต์ ํ๊ธฐ ๋ท๊ตฌ๋ฉ ๋ฐ์ดํฐ์ด๋ฏ๋ก ๋ฆฌ์กํธ ์์ง์ ์๋น(๋ฆฌ๋ ๋๋ง ๋ถ๋ด)๋ฅผ ๊ฑธ ํ์๊ฐ ์ ํ ์๋ useRef์ ์ต์ ๋ฌด๋์
๋๋ค.
Q2. ๋ค์ ์ค ์์ฒ ์ด๊ฐ ์ง useRef ์กฐ์์ ๋ํด, ๋ฆฌ์กํธ ํต์ฌ ํ ๋๋ฃ๊ฐ ๊ฐ์ฅ ๊ฒฝ์
(Horrify)ํ๊ณ ์ฝ๋ ๋ฆฌ๋ทฐ ์ ๋ฐ๋ก ๋ฐ๋ ค๋ฅผ ๋จน์ผ ์น๋ช
์ ํจํด์ ๋ฌด์์ธ๊ฐ์?
- A)
<input ref={myInputRef} />ํํ๋ก DOM ์์์ ์ง์ ๊ฐ๊ณ ๋ฆฌ๋ฅผ ๋์ง ๊ฒ. - B)
useEffect์ธ๋ถ ํด๋ฆฐ์ ๊ณต๊ฐ์์myRef.current = null๋ก ์ด๊ธฐํํ ๊ฒ. - C)
<div>๋ด ๋น๋ฐ ๊ธ๊ณ : {secretRef.current}</div>ํํ๋ก JSX ๋ ๋๋ง ๋ฐํ ๊ณต๊ฐ์์ ๋ณ์๋ฅผ ๋ฃ์ด๋ ๊ฒ. - D) ์ธ๋ถ ํ๊ฒฝ์
const initial = 'abc'๋ฅผ ๋นผ๋๊ณuseRef(initial)๋ก ๊ฐ์ ์ด๊ธฐ ์ธํ ํ ๊ฒ.
โ ์ ๋ต: C
๐ก ์์ธ ํด์ค: ์ํฐํจํด์
๋๋ค. useRef๋ ๊ฐ์ ์ ์ฅํ์ง๋ง ๋ณ๊ฒฝ ์ฌ์ค์ React ๋ ๋๋ฌ์ ์๋ฆฌ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ secretRef.current๋ฅผ JSX์ ์ง์ ๋ณด์ฌ์ฃผ๋ฉด ๊ฐ์ ๋ฐ๋์๋๋ฐ ํ๋ฉด์ ๊ฐฑ์ ๋์ง ์๋ ์ํ๊ฐ ์๊น๋๋ค. ํ๋ฉด์ ๋ณด์ฌ์ค ๊ฐ์ useState, ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ Effect์์๋ง ํ์ํ ๊ฐ์ useRef๋ก ๋๋๋ ๊ฒ์ด ์์ ํฉ๋๋ค. (A๋ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ, B์ D๋ ์ ์ ์ฌ์ฉ๋ฒ).
Q3. ์ฃผ๊ด์ ๋
ผ์ : useRef๊ฐ ์ปดํฌ๋ํธ์ ๋ ๋๋ง ํ์(์ฌ์คํ)์ ๊ด๊ณ์์ด ์ด๋ป๊ฒ ํญ์ "๋จ ํ๋์ ์จ์ ํ ํต(๋ฐ์ค)"์ ๊ธฐ์ตํ๊ณ ์๊ตฌ ๋ถ๋ณํ๊ฒ ์ ์ฅํ๋ ๊ตฌ์กฐ๋ฅผ ๋ฆฌ์กํธ ๋ด๋ถ์์ ํ๋ด(๊ตฌํ) ๋ด์์์ง, useState ๊ฐ๋
์ ๋น๋์ด ๊ทธ ๋น๋ฐ์ ์๋ ์๋ฆฌ๋ฅผ ์์ ํ์์ค.
โ ์ ๋ต ๋ฐ ์ฃผ๊ด์ ํด์ค:
๋ด๋ถ ์๋ ์๋ฆฌ: ๊ณต์ ๋ฌธ์ ๊ธฐ์ค์ผ๋ก useRef(initialValue)๋ current ์์ฑ์ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ฐํํ๊ณ , ๋ค์ ๋ ๋์์๋ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. initialValue๋ ์ฒซ ๋ ๋ ์ดํ์๋ ๋ค์ ์ฐ์ด์ง ์์ต๋๋ค.
ํต์ฌ์ "๊ฐ์ ref ๊ฐ์ฒด์ current๋ง ๋ฐ๋๊ณ , React ์ํ ํ์๋ ์๋ฌด ์
๋ฐ์ดํธ๋ ๋ค์ด๊ฐ์ง ์๋๋ค" ๋ ์ ์
๋๋ค. ๊ทธ๋์ ๊ฐ์ ๋ ๋ ์ฌ์ด์ ์ ์ง๋์ง๋ง, ๊ฐ ๋ณ๊ฒฝ๋ง์ผ๋ก ํ๋ฉด์ ๋ค์ ๊ทธ๋ ค์ง์ง ์์ต๋๋ค. ์ด ํน์ฑ ๋๋ถ์ ํ์ด๋จธ ID์ฒ๋ผ ํ๋ฉด๊ณผ ๋ฌด๊ดํ ๊ฐ์ ์์ ํ๊ฒ ๋ณด๊ดํ ์ ์๊ณ , ํ๋ฉด์ ๋ณด์ฌ์ค ๊ฐ์ state๋ก ๋ถ๋ฆฌํด์ผ ํฉ๋๋ค.
๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
ํ๋ฉด์ ๊ทธ๋ฆฌ์ง๋ ์์ ํ์ด๋จธ ์์ด๋๋ก ๋ฌด์๋ฏธํ ๋ ๋๋ง์ ๋ง๋ค๊ณ ์์๋ค๋, useRef๊ฐ ๋จ์ํ ํฌ์ปค์ค ์ก๋ ์ฉ๋๊ฐ ์๋๋ผ '์์ฃผ๋จธ๋ ๋น๋ฐ ๊ธ๊ณ '๋ผ๋ ๋น์ ๊ฐ ํต์ฌ์ ๊ดํตํ๋ค.
๐ก "์ํ(State)๋ ๋ง์ดํฌ, ์ฐธ์กฐ(Ref)๋ ๋น๋ฐ ๊ธ๊ณ . ๋ฐ์ดํฐ๊ฐ ๋ณํ ๋ ํ๋ฉด ํฝ์ ์ด ๋ฐ๋์ด์ผ ํ๋์ง ํ ๋ฒ๋ง ์๊ฐํด๋ณด์!"
์๋ฐ์คํฌ๋ฆฝํธ ๋ณ์๋ ๋ค๋ฅผ ๊ฒ ์์ง๋ง ์ปดํฌ๋ํธ ์๋ช
๋ด๋ด ์๊ตฌ ๋ณด์กด๋๋ค๋ ๊ฒ ์ ๊ธฐ์์ด๋ค. ๋น์ฅ ๋ด์ผ ์ถ๊ทผํด์ ์ธ๋ฐ์์ด ์ํ๋ก ๋นผ๋์ ์คํฌ๋กค ์์น๊ฐ์ด๋ ํ์ด๋จธ ์๋ณ์๋ค ๋ค useRef๋ก ๊ฐ์์์ด์ผ์ง. ์์ด ๋ปฅ ๋ซ๋ฆฌ๋ ๊ธฐ๋ถ์ด๋ค.