๋ Œ๋”๋ง ์ค‘์— ์ฝ๊ธฐ/์“ฐ๊ธฐ๋ฅผ ํ•˜์ง€ ์•Š๋Š” ref์˜ ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ๋ฒ•์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. useRef() ์‚ฌ์šฉ๋ฒ•์˜ โ€œ์ฃผ์˜ํ•˜์„ธ์š”!โ€ ์„น์…˜์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

๊ทœ์น™ ์„ธ๋ถ€ ์‚ฌํ•ญ

Ref๋Š” ๋ Œ๋”๋ง์— ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฐ’์„ ๋ณด์œ ํ•ฉ๋‹ˆ๋‹ค. State์™€ ๋‹ฌ๋ฆฌ ref๋ฅผ ๋ณ€๊ฒฝํ•ด๋„ ์žฌ๋ Œ๋”๋ง์ด ํŠธ๋ฆฌ๊ฑฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์ค‘์— ref.current๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋Š” ๊ฒƒ์€ React์˜ ์˜ˆ์ƒ์„ ๊นจ๋œจ๋ฆฝ๋‹ˆ๋‹ค. Ref๋Š” ์ฝ์œผ๋ ค๊ณ  ํ•  ๋•Œ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์•˜์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ทธ ๊ฐ’์€ ์˜ค๋ž˜๋˜์—ˆ๊ฑฐ๋‚˜ ์ผ๊ด€๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Ref ๊ฐ์ง€ ๋ฐฉ๋ฒ•

๋ฆฐํŠธ๋Š” ref๋กœ ์•Œ๊ณ  ์žˆ๋Š” ๊ฐ’์—๋งŒ ์ด๋Ÿฌํ•œ ๊ทœ์น™์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋‹ค์Œ ํŒจํ„ด ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ฐœ๊ฒฌํ•˜๋ฉด ref๋กœ ์ถ”๋ก ๋ฉ๋‹ˆ๋‹ค.

  • useRef() ๋˜๋Š” React.createRef()์—์„œ ๋ฐ˜ํ™˜๋œ ๊ฐ’

    const scrollRef = useRef(null);
  • ref๋กœ ๋ช…๋ช…๋˜๊ฑฐ๋‚˜ Ref๋กœ ๋๋‚˜๋Š” ์‹๋ณ„์ž๊ฐ€ .current๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋Š” ๊ฒฝ์šฐ

    buttonRef.current = node;
  • JSX ref prop์„ ํ†ตํ•ด ์ „๋‹ฌ๋œ ๊ฒฝ์šฐ (์˜ˆ: <div ref={someRef} />)

    <input ref={inputRef} />

๋ฌด์–ธ๊ฐ€๊ฐ€ ref๋กœ ํ‘œ์‹œ๋˜๋ฉด ๊ทธ ์ถ”๋ก ์€ ํ• ๋‹น, ๊ตฌ์กฐ ๋ถ„ํ•ด ๋˜๋Š” ํ—ฌํผ ํ˜ธ์ถœ์„ ํ†ตํ•ด ๊ฐ’์„ ๋”ฐ๋ผ๊ฐ‘๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ref๊ฐ€ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๋‹ค๋ฅธ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ref.current์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ๋ฆฐํŠธ๊ฐ€ ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ์œ„๋ฐ˜ ์‚ฌ๋ก€

  • ๋ Œ๋”๋ง ์ค‘์— ref.current ์ฝ๊ธฐ
  • ๋ Œ๋”๋ง ์ค‘์— refs ์—…๋ฐ์ดํŠธ
  • State์—ฌ์•ผ ํ•˜๋Š” ๊ฐ’์— refs ์‚ฌ์šฉ

์ž˜๋ชป๋œ ์˜ˆ์‹œ

์ด ๊ทœ์น™์— ๋Œ€ํ•œ ์ž˜๋ชป๋œ ์ฝ”๋“œ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

// โŒ ๋ Œ๋”๋ง ์ค‘์— ref ์ฝ๊ธฐ
function Component() {
const ref = useRef(0);
const value = ref.current; // ๋ Œ๋”๋ง ์ค‘์— ์ฝ์ง€ ๋งˆ์„ธ์š”
return <div>{value}</div>;
}

// โŒ ๋ Œ๋”๋ง ์ค‘์— ref ์ˆ˜์ •
function Component({value}) {
const ref = useRef(null);
ref.current = value; // ๋ Œ๋”๋ง ์ค‘์— ์ˆ˜์ •ํ•˜์ง€ ๋งˆ์„ธ์š”
return <div />;
}

์˜ฌ๋ฐ”๋ฅธ ์˜ˆ์‹œ

์ด ๊ทœ์น™์— ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ ์ฝ”๋“œ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

// โœ… Effect/ํ•ธ๋“ค๋Ÿฌ์—์„œ ref ์ฝ๊ธฐ
function Component() {
const ref = useRef(null);

useEffect(() => {
if (ref.current) {
console.log(ref.current.offsetWidth); // Effect์—์„œ๋Š” OK
}
});

return <div ref={ref} />;
}

// โœ… UI ๊ฐ’์—๋Š” state ์‚ฌ์šฉ
function Component() {
const [count, setCount] = useState(0);

return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}

// โœ… ref ๊ฐ’์˜ ์ง€์—ฐ ์ดˆ๊ธฐํ™”
function Component() {
const ref = useRef(null);

// ์ฒซ ์‚ฌ์šฉ ์‹œ ํ•œ ๋ฒˆ๋งŒ ์ดˆ๊ธฐํ™”
if (ref.current === null) {
ref.current = expensiveComputation(); // OK - ์ง€์—ฐ ์ดˆ๊ธฐํ™”
}

const handleClick = () => {
console.log(ref.current); // ์ดˆ๊ธฐํ™”๋œ ๊ฐ’ ์‚ฌ์šฉ
};

return <button onClick={handleClick}>Click</button>;
}

๋ฌธ์ œ ํ•ด๊ฒฐ

๋ฆฐํŠธ๊ฐ€ .current๊ฐ€ ์žˆ๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด๋ฅผ ํ”Œ๋ž˜๊ทธ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค

์ด๋ฆ„ ํœด๋ฆฌ์Šคํ‹ฑ์€ ์˜๋„์ ์œผ๋กœ ref.current์™€ fooRef.current๋ฅผ ์‹ค์ œ ref๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์ปค์Šคํ…€ ์ปจํ…Œ์ด๋„ˆ ๊ฐ์ฒด๋ฅผ ๋ชจ๋ธ๋งํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์ด๋ฆ„(์˜ˆ: box)์„ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ๊ฐ€๋ณ€ ๊ฐ’์„ state๋กœ ์ด๋™ํ•˜์„ธ์š”. ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ref๋กœ ์ถ”๋ก ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฐํŠธ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.