useRef
렌더링에 필요하지 않은 값을 참조할 수 있는 React Hook 😯
컴포넌트의 최상위 레벨에서 useRef를 호출하여 하나 이상의 ref를 선언한다.
import { useRef } from 'react';
function Stopwatch() {
const intervalRef = useRef(0);
💡useRef는 처음에 제공한 초기값으로 설정된 단일 current 프로퍼티가 있는 ref 객체를 반환한다.
💡다음 렌더링에서 useRef는 동일한 객체를 반환하고, 정보를 저장한다. 나중에 읽을 수 있도록 current 속성을 변경할 수 있다.
그럼 state와 뭐가 다른걸까❔
ref를 변경해도 리렌더링✖️
➡️ref는 컴포넌트의 시각적 출력에 영향을 미치지 않는 정보를 저장하는 데 적합하다.
import { useRef } from 'react';
export default function Counter() {
let ref = useRef(0);
function handleClick() {
ref.current = ref.current + 1;
alert('You clicked ' + ref.current + ' times!');
}
return (
<button onClick={handleClick}>
Click me!
</button>
);
}
import { useState, useRef } from 'react';
export default function Stopwatch() {
const [startTime, setStartTime] = useState(null);
const [now, setNow] = useState(null);
const intervalRef = useRef(null);
function handleStart() {
setStartTime(Date.now());
setNow(Date.now());
clearInterval(intervalRef.current);
intervalRef.current = setInterval(() => {
setNow(Date.now());
}, 10);
}
function handleStop() {
clearInterval(intervalRef.current);
}
let secondsPassed = 0;
if (startTime != null && now != null) {
secondsPassed = (now - startTime) / 1000;
}
return (
<>
<h1>Time passed: {secondsPassed.toFixed(3)}</h1>
<button onClick={handleStart}>
Start
</button>
<button onClick={handleStop}>
Stop
</button>
</>
);
}
텍스트 input에 초점 맞추기
버튼을 클릭하면 입력에 초점이 맞춰진다.
import { useRef } from 'react';
export default function Form() {
const inputRef = useRef(null);
function handleClick() {
inputRef.current.focus();
}
return (
<>
<input ref={inputRef} />
<button onClick={handleClick}>
Focus the input
</button>
</>
);
}
버튼을 클릭하면 이미지가 스크롤 된다. 목록 DOM 노드에 대한 ref를 사용한 다음 DOM querySelectorAll API를 호출하여 스크롤하려는 이미지를 찾는다.
import { useRef } from 'react';
export default function CatFriends() {
const listRef = useRef(null);
function scrollToIndex(index) {
const listNode = listRef.current;
// 다음 코드는 특정 DOM 구조를 가정합니다:
const imgNode = listNode.querySelectorAll('li > img')[index];
imgNode.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'center'
});
}
return (
<>
<nav>
<button onClick={() => scrollToIndex(0)}>
Neo
</button>
<button onClick={() => scrollToIndex(1)}>
Millie
</button>
<button onClick={() => scrollToIndex(2)}>
Bella
</button>
</nav>
<div>
<ul ref={listRef}>
<li>
<img
src="https://placecats.com/neo/300/200"
alt="Neo"
/>
</li>
<li>
<img
src="https://placecats.com/millie/200/200"
alt="Millie"
/>
</li>
<li>
<img
src="https://placecats.com/bella/199/200"
alt="Bella"
/>
</li>
</ul>
</div>
</>
);
}