๐Ÿถ useRef()

๋ฆฌ์•กํŠธ์—์„œ ref๋Š” ์ฃผ๋กœ DOM ๋…ธ๋“œ ์ฐธ์กฐ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ๊ฐ’ ์ฐธ์กฐ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

useRef()๋Š” ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ํŠน์ • ๊ฐ’์„ ์ง€์†์ ์œผ๋กœ ์ฐธ์กฐํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. useState()์™€ ๋‹ฌ๋ฆฌ useRef()๋Š” ํ˜„์žฌ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด๋„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์•„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
// useRef() ํ›…์„ ์‚ฌ์šฉํ•ด ์นด์šดํŠธ ์ฐธ์กฐ ์ƒ์„ฑ
const countRef = useRef(0);

// ์นด์šดํŠธ ์ฐธ์กฐ์˜ ํ˜„์žฌ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์–ด๋„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค์‹œ ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์Œ
countRef.current = countRef.current + 1;

ํด๋ž˜์Šค๋Š” ์ž์‹ ์˜ ์ธ์Šคํ„ด์Šค ๋ฉค๋ฒ„๋ฅผ ์‚ฌ์šฉํ•ด ๋ Œ๋”๋ง ์ƒ๊ด€์—†์ด ํŠน์ • ๊ฐ’์„ ๊ธฐ์–ตํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๋ฐ˜ํ•ด, ํ•จ์ˆ˜๋Š” ๋‹ค์‹œ ๋ Œ๋”๋ง ๋˜๋ฉด ๋งค๋ฒˆ ํ•จ์ˆ˜ ๋ชธ์ฒด๊ฐ€ ์ดˆ๊ธฐํ™” ๋˜๋ฏ€๋กœ ํŠน์ • ๊ฐ’์„ ๊ธฐ์–ตํ•  ๋•Œ useRef()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์œ ์šฉํ•˜๋‹ค.

๐Ÿฅ useRef() ์‚ฌ์šฉ๋ชฉ์ 

1. DOM ์š”์†Œ ์ ‘๊ทผ ๋ฐ ์กฐ์ž‘

๋ฆฌ์•กํŠธ render() ๋‹จ๊ณ„์—์„œ๋Š” DOM์ด ๊ทธ๋ ค์ง€๊ธฐ ์ „ ๋‹จ๊ณ„์ด๋ฏ€๋กœ DOM์— ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

ํ•˜์ง€๋งŒ useRef()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ mount๋œ ์‹œ์  ์ดํ›„ DOM ์š”์†Œ์— ์ ‘๊ทผํ•˜์—ฌ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
  • ์•„์ง DOM์ด ๊ทธ๋ ค์ง€๊ธฐ ์ „์ด๋ผ DOM ์š”์†Œ์— ์ ‘๊ทผํ•˜์—ฌ focus()๋ฅผ ํ™œ์„ฑํ™” ์‹œํ‚ฌ ์ˆ˜ ์—†์ง€๋งŒ, useRef()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ DOM ์š”์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

2. ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ํŠน์ • ๊ฐ’์„ ๊ธฐ์–ต

ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ํŠน์ • ๊ฐ’์„ ๊ธฐ์–ตํ•˜๋ฉด์„œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด๋„ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์•„์•ผํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { useEffect, useRef, useState } from "react";
import randomcolor from "randomcolor";

function DoNotReRender() {
const colorRef = useRef(0);
const [stateValue, setStateValue] = useState(0);
const [stateHex, setStateHex] = useState(randomcolor());
const [refHex, setRefHex] = useState(randomcolor());

useEffect(() => {
setStateHex(randomcolor());
}, [stateValue]);

useEffect(() => {
setRefHex(randomcolor());
}, [colorRef]);

return (
<Grid lang="en">
<GridItem
css={`
background: ${stateHex};
`}
>
<h2>State</h2>
<ChangeColorButton
aria-label="state ์ปฌ๋Ÿฌ ๋ณ€๊ฒฝ"
onClick={() => setStateValue(stateValue + 1)}
/>
<p>์ปฌ๋Ÿฌ ๋ณ€๊ฒฝ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค.</p>
</GridItem>
<GridItem
css={`
background: ${refHex};
`}
onClick={() => {
colorRef.current += 10;
console.log(`colorRef.current = ${colorRef.current}`);
}}
>
<h2>Ref</h2>
<ChangeColorButton aria-label="ref ์ปฌ๋Ÿฌ ๋ณ€๊ฒฝ" />
<p>์ปฌ๋Ÿฌ ๋ณ€๊ฒฝ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋ ๊นŒ์š”?</p>
</GridItem>
</Grid>
);
}
  • useState()์˜ setStateValue()๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์„ ๋ณ€๊ฒฝํ•œ ๊ฒฝ์šฐ ์žฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•˜์ง€๋งŒ, useRef()์˜ current ๊ฐ’์„ ๊ฐฑ์‹ ํ•˜๋ฉด ์žฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.